@hology/core 0.0.55 → 0.0.57
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/config/project-config.d.ts +5 -0
- package/dist/csm.d.ts +2 -3
- package/dist/csm.js +1 -1
- package/dist/effects/vfx/trail-renderer.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/gameplay/actors/builtin/camera-actor.d.ts +0 -6
- package/dist/gameplay/actors/builtin/camera-actor.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.d.ts +7 -2
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/initiate.d.ts +4 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/services/asset-loader.d.ts +1 -0
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/rendering.d.ts +5 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +3 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/landscape/landscape.js +1 -1
- package/dist/scene/materializer.d.ts +6 -7
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/materials/grass-foliage.js +1 -1
- package/dist/scene/sky.js +1 -1
- package/dist/shader-nodes/effects.d.ts +2 -2
- package/dist/shader-nodes/effects.js +1 -1
- package/dist/shader-nodes/landscape.js +1 -1
- package/dist/shader-nodes/layers.js +1 -1
- package/dist/shader-nodes/shapes.js +1 -1
- package/dist/shader-nodes/voronoi.js +1 -1
- package/dist/utils/three/gpu-stats-panel.d.ts +10 -0
- package/dist/utils/three/gpu-stats-panel.js +5 -0
- package/dist/utils/three/outline-pass.d.ts +0 -1
- package/package.json +6 -5
- package/tsconfig.tsbuildinfo +1 -1
package/dist/csm.d.ts
CHANGED
@@ -7,7 +7,6 @@ export declare const CSMUtil: {
|
|
7
7
|
patchThreeAdd(): void;
|
8
8
|
};
|
9
9
|
export declare const CSMShader: {
|
10
|
-
lights_fragment_begin:
|
11
|
-
|
12
|
-
lights_pars_begin: (maxCascades: number) => string;
|
10
|
+
lights_fragment_begin: string;
|
11
|
+
lights_pars_begin: string;
|
13
12
|
};
|
package/dist/csm.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import*as t from"three";const i={add:t.Object3D.prototype.add,attach:t.Object3D.prototype.attach},e=new WeakMap,n=new WeakMap;export const CSMUtil=new class{constructor(){this.renderingView=null}onBeforeCompile(i,e){i.defines=i.defines||{},i.defines.USE_CSM=1,i.defines.CSM_CASCADES=this.renderingView.csm.cascades,console.log(e.fragmentShader);const n=this.renderingView.camera instanceof t.PerspectiveCamera?this.renderingView.camera.far:Number.MAX_SAFE_INTEGER,o=this.renderingView.camera instanceof t.PerspectiveCamera?this.renderingView.camera.near:0,a=Math.min(n,this.renderingView.csm.maxFar),r=[];this.renderingView.csm.getExtendedBreaks(r),e.uniforms.CSM_cascades={value:r},e.uniforms.cameraNear={value:o},e.uniforms.shadowFar={value:a}}patchThreeAdd(){const o=this.renderingView;e.set(o.scene,o.csm);for(const[o,a]of Object.entries(i))t.Object3D.prototype[o]=function(...i){let o=this;for(;null!=o.parent;)o=o.parent;const r=o,d=e.get(r);if(null==d)return a.apply(this,arguments),this;n.has(r)||n.set(r,new WeakSet);const h=n.get(r);function c(t){t&&!h.has(t)&&(h.add(t),d?.setupMaterial(t))}return i.forEach((i=>i?.traverse((i=>{if(i instanceof t.Mesh||i instanceof t.SkinnedMesh)if(i.material instanceof Array)for(const t of i.material)c(t);else c(i.material)})))),a.apply(this,arguments),this}}};import{ShaderChunk as o}from"three";const a=o.lights_pars_begin;export const CSMShader={lights_fragment_begin:t=>"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n\n#ifdef USE_CLEARCOAT\n\n\tgeometryClearcoatNormal = clearcoatNormal;\n\n#endif\n\n#ifdef USE_IRIDESCENCE\n\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\n\tif ( material.iridescenceThickness == 0.0 ) {\n\n\t\tmaterial.iridescence = 0.0;\n\n\t} else {\n\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\n\t}\n\n\tif ( material.iridescence > 0.0 ) {\n\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\n\t\t// Iridescence F0 approximation\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\n\t}\n\n#endif\n\nIncidentLight directLight;\n\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\n\t\tpointLight = pointLights[ i ];\n\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\n\t\tspotLight = spotLights[ i ];\n\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t// spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\tdirectionalLight = directionalLights[ i ];\n\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\tRectAreaLight rectAreaLight;\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if defined( RE_IndirectDiffuse )\n\n\tvec3 iblIrradiance = vec3( 0.0 );\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n#if defined( RE_IndirectSpecular )\n\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n\n#endif\n\t",lights_fragment_begi2:t=>`\nGeometricContext geometry;\n\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n\n#ifdef CLEARCOAT\n\n\tgeometry.clearcoatNormal = clearcoatNormal;\n\n#endif\n\nIncidentLight directLight;\n\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\n\t\tpointLight = pointLights[ i ];\n\n\t\tgetPointLightInfo( pointLight, geometry, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\n\t\tspotLight = spotLights[ i ];\n\n\t\tgetSpotLightInfo( spotLight, geometry, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_DIR_LIGHTS > 0) && defined( RE_Direct ) && defined( USE_CSM ) && defined( CSM_CASCADES )\n\n\tDirectionalLight directionalLight;\n\tfloat linearDepth = (vViewPosition.z) / (shadowFar - cameraNear);\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#if defined( USE_SHADOWMAP ) && defined( CSM_FADE ) && CSM_FADE == 1\n\tvec2 cascade;\n\tfloat cascadeCenter;\n\tfloat closestEdge;\n\tfloat margin;\n\tfloat csmx;\n\tfloat csmy;\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\n\t \t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t// NOTE: Depth gets larger away from the camera.\n\t\t\t// cascade.x is closer, cascade.y is further\n\n\t\t\t\t#if ( UNROLLED_LOOP_INDEX < ${t} )\n\n\t\t\t\t\t// NOTE: Apply CSM shadows\n\n\t\t\t\t\tcascade = CSM_cascades[ i ];\n\t\t\t\t\tcascadeCenter = ( cascade.x + cascade.y ) / 2.0;\n\t\t\t\t\tclosestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;\n\t\t\t\t\tmargin = 0.25 * pow( closestEdge, 2.0 );\n\t\t\t\t\tcsmx = cascade.x - margin / 2.0;\n\t\t\t\t\tcsmy = cascade.y + margin / 2.0;\n\t\t\t\t\tif( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {\n\n\t\t\t\t\t\tfloat dist = min( linearDepth - csmx, csmy - linearDepth );\n\t\t\t\t\t\tfloat ratio = clamp( dist / margin, 0.0, 1.0 );\n\n\t\t\t\t\t\tvec3 prevColor = directLight.color;\n\t\t\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\n\t\t\t\t\t\tbool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;\n\t\t\t\t\t\tdirectLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );\n\n\t\t\t\t\t\tReflectedLight prevLight = reflectedLight;\n\t\t\t\t\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t\t\t\t\t\tbool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;\n\t\t\t\t\t\tfloat blendRatio = shouldBlend ? ratio : 1.0;\n\n\t\t\t\t\t\treflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );\n\t\t\t\t\t\treflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio );\n\t\t\t\t\t\treflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio );\n\t\t\t\t\t\treflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio );\n\n\t\t\t\t\t}\n\n\t\t\t\t#else\n\n\t\t\t\t\t// NOTE: Apply the reminder of directional lights\n\n\t\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\n\t\t\t\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t\t\t\t#endif\n\n\t \t#endif\n\n\t}\n\t#pragma unroll_loop_end\n\t#else\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\n\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) \n\n\t\t\t\t#if ( UNROLLED_LOOP_INDEX < ${t} )\n\n\t\t\t\t\t// NOTE: Apply CSM shadows\n\n\t\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t\tif(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\n\t\t\t\t\tif(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometry, material, reflectedLight );\n\n\t\t\t\t#else\n\n\t\t\t\t\t// NOTE: Apply the reminder of directional lights\n\n\t\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\n\t\t\t\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t\t\t\t#endif\n\n\t\t\t#endif\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n\t#if ( NUM_DIR_LIGHTS > NUM_DIR_LIGHT_SHADOWS)\n\t\t// compute the lights not casting shadows (if any)\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = NUM_DIR_LIGHT_SHADOWS; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\t\tdirectionalLight = directionalLights[ i ];\n\n\t\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\n\t\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && !defined( USE_CSM ) && !defined( CSM_CASCADES )\n\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\tdirectionalLight = directionalLights[ i ];\n\n\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\tRectAreaLight rectAreaLight;\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if defined( RE_IndirectDiffuse )\n\n\tvec3 iblIrradiance = vec3( 0.0 );\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry.normal );\n\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n#if defined( RE_IndirectSpecular )\n\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n\n#endif\n`,lights_pars_begin:t=>a};
|
1
|
+
import*as t from"three";const e={add:t.Object3D.prototype.add,attach:t.Object3D.prototype.attach},i=new WeakMap,n=new WeakMap;export const CSMUtil=new class{constructor(){this.renderingView=null}onBeforeCompile(e,i){e.defines=e.defines||{},e.defines.USE_CSM=1,e.defines.CSM_CASCADES=this.renderingView.csm.cascades;const n=this.renderingView.camera instanceof t.PerspectiveCamera?this.renderingView.camera.far:Number.MAX_SAFE_INTEGER,a=this.renderingView.camera instanceof t.PerspectiveCamera?this.renderingView.camera.near:0,o=Math.min(n,this.renderingView.csm.maxFar),r=[];this.renderingView.csm.getExtendedBreaks(r),i.uniforms.CSM_cascades={value:r},i.uniforms.cameraNear={value:a},i.uniforms.shadowFar={value:o}}patchThreeAdd(){const a=this.renderingView;i.set(a.scene,a.csm);for(const[a,o]of Object.entries(e))t.Object3D.prototype[a]=function(...e){let a=this;for(;null!=a.parent;)a=a.parent;const r=a,d=i.get(r);if(null==d)return o.apply(this,arguments),this;n.has(r)||n.set(r,new WeakSet);const c=n.get(r);function h(t){t&&!c.has(t)&&(c.add(t),d?.setupMaterial(t))}return e.forEach((e=>e?.traverse((e=>{if(e instanceof t.Mesh||e instanceof t.SkinnedMesh)if(e.material instanceof Array)for(const t of e.material)h(t);else h(e.material)})))),o.apply(this,arguments),this}}};import{ShaderChunk as a}from"three";a.lights_pars_begin;export const CSMShader={lights_fragment_begin:"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n\n#ifdef USE_CLEARCOAT\n\n\tgeometryClearcoatNormal = clearcoatNormal;\n\n#endif\n\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\t// Iridescence F0 approximation\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\n\nIncidentLight directLight;\n\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\n\t\tpointLight = pointLights[ i ];\n\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tSpotLight spotLight;\n \tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\n\t\tspotLight = spotLights[ i ];\n\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n \t\t// spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && defined( USE_CSM ) && defined( CSM_CASCADES )\n\n\tDirectionalLight directionalLight;\n\tfloat linearDepth = (vViewPosition.z) / (shadowFar - cameraNear);\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )\n\t\tvec2 cascade;\n\t\tfloat cascadeCenter;\n\t\tfloat closestEdge;\n\t\tfloat margin;\n\t\tfloat csmx;\n\t\tfloat csmy;\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// NOTE: Depth gets larger away from the camera.\n\t\t\t\t// cascade.x is closer, cascade.y is further\n\t\t\t\tcascade = CSM_cascades[ i ];\n\t\t\t\tcascadeCenter = ( cascade.x + cascade.y ) / 2.0;\n\t\t\t\tclosestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;\n\t\t\t\tmargin = 0.25 * pow( closestEdge, 2.0 );\n\t\t\t\tcsmx = cascade.x - margin / 2.0;\n\t\t\t\tcsmy = cascade.y + margin / 2.0;\n\t\t\t\tif( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {\n\n\t\t\t\t\tfloat dist = min( linearDepth - csmx, csmy - linearDepth );\n\t\t\t\t\tfloat ratio = clamp( dist / margin, 0.0, 1.0 );\n\n\t\t\t\t\tvec3 prevColor = directLight.color;\n\t\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\n\t\t\t\t\tbool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;\n\t\t\t\t\tdirectLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );\n\n\t\t\t\t\tReflectedLight prevLight = reflectedLight;\n\t\t\t\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t\t\t\t\tbool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;\n\t\t\t\t\tfloat blendRatio = shouldBlend ? ratio : 1.0;\n\n\t\t\t\t\treflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );\n\t\t\t\t\treflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio );\n\t\t\t\t\treflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio );\n\t\t\t\t\treflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio );\n\n\t\t\t\t}\n\t\t\t#endif\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#elif defined (USE_SHADOWMAP)\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\n\t\t\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\tif(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\n\t\t\t\tif(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t\t\t#endif\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#elif ( NUM_DIR_LIGHT_SHADOWS > 0 )\n\t\t// note: no loop here - all CSM lights are in fact one light only\n\t\tgetDirectionalLightInfo( directionalLights[0], directLight );\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t#endif\n\n\t#if ( NUM_DIR_LIGHTS > NUM_DIR_LIGHT_SHADOWS)\n\t\t// compute the lights not casting shadows (if any)\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = NUM_DIR_LIGHT_SHADOWS; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\t\tdirectionalLight = directionalLights[ i ];\n\n\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) && !defined( USE_CSM ) && !defined( CSM_CASCADES )\n\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\tdirectionalLight = directionalLights[ i ];\n\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\tRectAreaLight rectAreaLight;\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if defined( RE_IndirectDiffuse )\n\n\tvec3 iblIrradiance = vec3( 0.0 );\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n#if defined( RE_IndirectSpecular )\n\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n\n#endif\n",lights_pars_begin:"\n#if defined( USE_CSM ) && defined( CSM_CASCADES )\nuniform vec2 CSM_cascades[CSM_CASCADES];\nuniform float cameraNear;\nuniform float shadowFar;\n#endif\n\t"+a.lights_pars_begin};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import*as e from"three";export class Trail extends e.Object3D{constructor(t,r){super(),this.nodeCenters=[],this.nodeIDs=[],this.advance=function(){const t=new e.Matrix4;return function(){this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.advanceWithTransform(t),this.updateUniforms()}}(),this.advanceGeometry=function(e,t){const r=this.currentEnd+1>=this.length?0:this.currentEnd+1;if(t?this.updateNodePositionsFromTransformMatrix(r,t):this.updateNodePositionsFromOrientationTangent(r,e.position,e.tangent),this.currentLength>=1&&(this.connectNodes(this.currentEnd,r),this.currentLength>=this.length)){const e=this.currentEnd+1>=this.length?0:this.currentEnd+1;this.disconnectNodes(e)}this.currentLength<this.length&&this.currentLength++,this.currentEnd++,this.currentEnd>=this.length&&(this.currentEnd=0),this.currentLength>=1&&(this.currentLength<this.length?this.geometry.setDrawRange(0,(this.currentLength-1)*this.FaceIndicesPerNode):this.geometry.setDrawRange(0,this.currentLength*this.FaceIndicesPerNode)),this.updateNodeID(this.currentEnd,this.currentNodeID),this.currentNodeID++},this.updateHead=function(){const t=new e.Matrix4;return function(){this.currentEnd<0||(this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.updateNodePositionsFromTransformMatrix(this.currentEnd,t))}}(),this.updateNodePositionsFromOrientationTangent=function(){const t=new e.Quaternion,r=new e.Vector3,i=[];for(let t=0;t<Trail.MaxHeadVertices;t++){const t=new e.Vector3;i.push(t)}return function(e,a,n){const s=this.geometry.getAttribute("position");this.updateNodeCenter(e,a),r.copy(a),r.sub(Trail.LocalHeadOrigin),t.setFromUnitVectors(Trail.LocalOrientationTangent,n);for(let e=0;e<this.localHeadGeometry.length;e++){const a=i[e];a.copy(this.localHeadGeometry[e]),a.applyQuaternion(t),a.add(r)}for(let t=0;t<this.localHeadGeometry.length;t++){const r=(this.VerticesPerNode*e+t)*Trail.PositionComponentCount,a=i[t];s.array[r]=a.x,s.array[r+1]=a.y,s.array[r+2]=a.z}s.needsUpdate=!0}}(),this.updateNodePositionsFromTransformMatrix=function(){const t=new e.Matrix3,r=new e.Quaternion,i=new e.Vector3,a=new e.Vector3,n=new e.Vector3,s=new e.Vector3,o=[];for(let t=0;t<Trail.MaxHeadVertices;t++){const t=new e.Vector3;o.push(t)}return function(h,c){const l=this.geometry.getAttribute("position");i.set(0,0,0),i.applyMatrix4(c),this.updateNodeCenter(h,i);for(let e=0;e<this.localHeadGeometry.length;e++){o[e].copy(this.localHeadGeometry[e])}for(let e=0;e<this.localHeadGeometry.length;e++){o[e].applyMatrix4(c)}if(this.lastNodeCenter&&this.orientToMovement&&(function(e,t){const r=t.elements;e.set(r[0],r[1],r[2],r[4],r[5],r[6],r[8],r[9],r[10])}(t,c),n.set(0,0,-1),n.applyMatrix3(t),s.copy(this.currentNodeCenter),s.sub(this.lastNodeCenter),s.normalize(),s.lengthSq()<=1e-4&&this.lastOrientationDir&&s.copy(this.lastOrientationDir),s.lengthSq()>1e-4)){this.lastOrientationDir||(this.lastOrientationDir=new e.Vector3),r.setFromUnitVectors(n,s),a.copy(this.currentNodeCenter);for(let e=0;e<this.localHeadGeometry.length;e++){const t=o[e];t.sub(a),t.applyQuaternion(r),t.add(a)}}for(let e=0;e<this.localHeadGeometry.length;e++){const t=(this.VerticesPerNode*h+e)*Trail.PositionComponentCount,r=o[e];l.array[t]=r.x,l.array[t+1]=r.y,l.array[t+2]=r.z}l.needsUpdate=!0,l.updateRange.offset=h*this.VerticesPerNode*Trail.PositionComponentCount,l.updateRange.count=this.VerticesPerNode*Trail.PositionComponentCount}}(),this.connectNodes=function(){const e={attribute:null,offset:0,count:-1};return function(t,r){const i=this.geometry.getIndex();for(let e=0;e<this.localHeadGeometry.length-1;e++){const a=this.VerticesPerNode*t+e,n=this.VerticesPerNode*r+e,s=(t*this.FacesPerNode+e*Trail.FacesPerQuad)*Trail.IndicesPerFace;i.array[s]=a,i.array[s+1]=n,i.array[s+2]=a+1,i.array[s+3]=n,i.array[s+4]=n+1,i.array[s+5]=a+1}return i.needsUpdate=!0,i.updateRange.count=-1,e.attribute=i,e.offset=t*this.FacesPerNode*Trail.IndicesPerFace,e.count=this.FacesPerNode*Trail.IndicesPerFace,e}}(),this.disconnectNodes=function(){const e={attribute:null,offset:0,count:-1};return function(t){const r=this.geometry.getIndex();for(let e=0;e<this.localHeadGeometry.length-1;e++){const i=(t*this.FacesPerNode+e*Trail.FacesPerQuad)*Trail.IndicesPerFace;r.array[i]=0,r.array[i+1]=0,r.array[i+2]=0,r.array[i+3]=0,r.array[i+4]=0,r.array[i+5]=0}return r.needsUpdate=!0,r.updateRange.count=-1,e.attribute=r,e.offset=t*this.FacesPerNode*Trail.IndicesPerFace,e.count=this.FacesPerNode*Trail.IndicesPerFace,e}}(),this.active=!1,this.orientToMovement=!1,r&&(this.orientToMovement=!0),this.scene=t,this.geometry=null,this.mesh=null,this.nodeCenters=[],this.lastNodeCenter=null,this.currentNodeCenter=null,this.lastOrientationDir=null,this.nodeIDs=[],this.currentLength=0,this.currentEnd=0,this.currentNodeID=0,this.advanceFrequency=60,this.advancePeriod=1/this.advanceFrequency,this.lastAdvanceTime=0,this.paused=!1,this.pauseAdvanceUpdateTimeDiff=0}setAdvanceFrequency(e){this.advanceFrequency=e,this.advancePeriod=1/this.advanceFrequency}initialize(t,r,i,a,n,s){this.deactivate(),this.destroyMesh(),this.length=r>0?r+1:0,this.dragTexture=i?1:0,this.targetObject=s,this.initializeLocalHeadGeometry(a,n),this.nodeIDs=[],this.nodeCenters=[];for(let t=0;t<this.length;t++)this.nodeIDs[t]=-1,this.nodeCenters[t]=new e.Vector3;this.material=t,this.initializeGeometry(),this.initializeMesh(),this.material.uniforms.trailLength.value=0,this.material.uniforms.minID.value=0,this.material.uniforms.maxID.value=0,this.material.uniforms.dragTexture.value=this.dragTexture,this.material.uniforms.maxTrailLength.value=this.length,this.material.uniforms.verticesPerNode.value=this.VerticesPerNode,this.material.uniforms.textureTileFactor.value=new e.Vector2(1,1),this.material.uniforms.scale.value=1,this.reset()}initializeLocalHeadGeometry(t,r){if(this.localHeadGeometry=[],r){this.VerticesPerNode=0;for(let t=0;t<r.length&&t<Trail.MaxHeadVertices;t++){const i=r[t];if(i&&i instanceof e.Vector3){const t=new e.Vector3;t.copy(i),this.localHeadGeometry.push(t),this.VerticesPerNode++}}}else{const r=(t||1)/2;this.localHeadGeometry.push(new e.Vector3(-r,0,0)),this.localHeadGeometry.push(new e.Vector3(r,0,0)),this.VerticesPerNode=2}this.FacesPerNode=2*(this.VerticesPerNode-1),this.FaceIndicesPerNode=3*this.FacesPerNode}initializeGeometry(){this.vertexCount=this.length*this.VerticesPerNode,this.faceCount=this.length*this.FacesPerNode;const t=new e.BufferGeometry,r=new Float32Array(this.vertexCount),i=new Float32Array(this.vertexCount*this.VerticesPerNode),a=new Float32Array(this.vertexCount*Trail.PositionComponentCount),n=new Float32Array(this.vertexCount*Trail.PositionComponentCount),s=new Float32Array(this.vertexCount*Trail.UVComponentCount),o=new Uint32Array(this.faceCount*Trail.IndicesPerFace),h=new e.BufferAttribute(r,1);h.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeID",h);const c=new e.BufferAttribute(i,1);c.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeVertexID",c);const l=new e.BufferAttribute(n,Trail.PositionComponentCount);l.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeCenter",l);const d=new e.BufferAttribute(a,Trail.PositionComponentCount);d.setUsage(e.DynamicDrawUsage),t.setAttribute("position",d);const u=new e.BufferAttribute(s,Trail.UVComponentCount);u.setUsage(e.DynamicDrawUsage),t.setAttribute("uv",u);const m=new e.BufferAttribute(o,1);m.setUsage(e.DynamicDrawUsage),t.setIndex(m),this.geometry=t}zeroVertices(){const e=this.geometry.getAttribute("position");for(let t=0;t<this.vertexCount;t++){const r=3*t;e.array[r]=0,e.array[r+1]=0,e.array[r+2]=0}e.needsUpdate=!0}zeroIndices(){if(null==this.geometry)throw"Geometry not initialized";const e=this.geometry.getIndex();for(let t=0;t<this.faceCount;t++){const r=3*t;e.array[r]=0,e.array[r+1]=0,e.array[r+2]=0}e.needsUpdate=!0,e.addUpdateRange(0,-1)}formInitialFaces(){this.zeroIndices();const e=this.geometry.getIndex();for(let e=0;e<this.length-1;e++)this.connectNodes(e,e+1);e.needsUpdate=!0,e.addUpdateRange(0,-1)}initializeMesh(){if(null==this.geometry)throw"Geometry not initialized";this.mesh=new e.Mesh(this.geometry,this.material),this.mesh.matrixAutoUpdate=!1}destroyMesh(){this.mesh&&(this.scene.remove(this.mesh),this.mesh=null)}reset(){this.currentLength=0,this.currentEnd=-1,this.lastNodeCenter=null,this.currentNodeCenter=null,this.lastOrientationDir=null,this.currentNodeID=0,this.formInitialFaces(),this.zeroVertices(),this.geometry.setDrawRange(0,0)}updateUniforms(){this.currentLength<this.length?this.material.uniforms.minID.value=0:this.material.uniforms.minID.value=this.currentNodeID-this.length,this.material.uniforms.maxID.value=this.currentNodeID,this.material.uniforms.trailLength.value=this.currentLength,this.material.uniforms.maxTrailLength.value=this.length,this.material.uniforms.verticesPerNode.value=this.VerticesPerNode}advanceWithPositionAndOrientation(e,t){this.advanceGeometry({position:e,tangent:t},null)}advanceWithTransform(e){this.advanceGeometry(null,e)}currentTime(){return performance.now()/1e3}pause(){this.paused||(this.paused=!0,this.pauseAdvanceUpdateTimeDiff=this.currentTime()-this.lastAdvanceTime)}resume(){this.paused&&(this.paused=!1,this.lastAdvanceTime=this.currentTime()-this.pauseAdvanceUpdateTimeDiff)}update(){if(!this.paused){const e=this.currentTime();this.lastAdvanceTime||(this.lastAdvanceTime=e),e-this.lastAdvanceTime>this.advancePeriod?(this.advance(),this.lastAdvanceTime=e):this.updateHead()}}updateNodeID(e,t){this.nodeIDs[e]=t;const r=this.geometry.getAttribute("nodeID"),i=this.geometry.getAttribute("nodeVertexID");for(let a=0;a<this.VerticesPerNode;a++){const n=e*this.VerticesPerNode+a;r.array[n]=t,i.array[n]=a}r.needsUpdate=!0,i.needsUpdate=!0,r.updateRange.offset=e*this.VerticesPerNode,r.updateRange.count=this.VerticesPerNode,i.updateRange.offset=e*this.VerticesPerNode,i.updateRange.count=this.VerticesPerNode}updateNodeCenter(e,t){this.lastNodeCenter=this.currentNodeCenter,this.currentNodeCenter=this.nodeCenters[e],this.currentNodeCenter.copy(t);const r=this.geometry.getAttribute("nodeCenter");for(let i=0;i<this.VerticesPerNode;i++){const a=3*(e*this.VerticesPerNode+i);r.array[a]=t.x,r.array[a+1]=t.y,r.array[a+2]=t.z}r.needsUpdate=!0,r.updateRange.offset=e*this.VerticesPerNode*Trail.PositionComponentCount,r.updateRange.count=this.VerticesPerNode*Trail.PositionComponentCount}deactivate(){this.active&&(this.scene.remove(this.mesh),this.active=!1)}activate(){this.active||(this.scene.add(this.mesh),this.active=!0)}static createMaterial(t,r,i){return(i=i||{}).trailLength={type:"f",value:null},i.verticesPerNode={type:"f",value:null},i.minID={type:"f",value:null},i.maxID={type:"f",value:null},i.dragTexture={type:"f",value:null},i.maxTrailLength={type:"f",value:null},i.textureTileFactor={type:"v2",value:null},i.headColor={type:"v4",value:new e.Vector4},i.tailColor={type:"v4",value:new e.Vector4},i.taper={type:"bool",value:!1},i.scale={type:"f",value:1},t=t||Trail.Shader.BaseVertexShader,r=r||Trail.Shader.BaseFragmentShader,new e.ShaderMaterial({uniforms:i,vertexShader:t,fragmentShader:r,transparent:!0,alphaTest:.5,blending:e.CustomBlending,blendSrc:e.SrcAlphaFactor,blendDst:e.OneMinusSrcAlphaFactor,blendEquation:e.AddEquation,depthTest:!0,depthWrite:!1,side:e.DoubleSide})}static createBaseMaterial(e={}){return Trail.createMaterial(Trail.Shader.BaseVertexShader,Trail.Shader.BaseFragmentShader,e)}static createTexturedMaterial(e){return(e={}).trailTexture={type:"t",value:null},Trail.createMaterial(Trail.Shader.TexturedVertexShader,Trail.Shader.TexturedFragmentShader,e)}static get MaxHeadVertices(){return 128}static{this._LocalOrientationTangent=new e.Vector3(1,0,0)}static get LocalOrientationTangent(){return Trail._LocalOrientationTangent}static{this._LocalHeadOrigin=new e.Vector3(0,0,0)}static get LocalHeadOrigin(){return Trail._LocalHeadOrigin}static get PositionComponentCount(){return 3}static get UVComponentCount(){return 2}static get IndicesPerFace(){return 3}static get FacesPerQuad(){return 2}static{this.Shader={get BaseVertexVars(){return["attribute float nodeID;","attribute float nodeVertexID;","attribute vec3 nodeCenter;","uniform float minID;","uniform float maxID;","uniform float trailLength;","uniform float maxTrailLength;","uniform float verticesPerNode;","uniform vec2 textureTileFactor;","uniform bool taper;","uniform vec4 headColor;","uniform vec4 tailColor;","varying vec4 vColor;"].join("\n")},get TexturedVertexVars(){return[this.BaseVertexVars,"varying vec2 vUV;","uniform float dragTexture;"].join("\n")},BaseFragmentVars:["varying vec4 vColor;","uniform sampler2D trailTexture;"].join("\n"),get TexturedFragmentVars(){return[this.BaseFragmentVars,"varying vec2 vUV;"].join("\n")},get VertexShaderCore(){return["float fraction = (maxID - nodeID) / (maxID - minID);","float fractionSize = taper ? fraction : 0.0;","vColor = (1.0 - fraction) * headColor + fraction * tailColor;","vec4 realPosition = vec4((1.0 - fractionSize) * position.xyz + fractionSize * nodeCenter.xyz, 1.0); "].join("\n")},get BaseVertexShader(){return[this.BaseVertexVars,"void main() { ",this.VertexShaderCore,"gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get BaseFragmentShader(){return[this.BaseFragmentVars,"void main() { ","gl_FragColor = vColor;","}"].join("\n")},get TexturedVertexShader(){return[this.TexturedVertexVars,"void main() { ",this.VertexShaderCore,"float s = 0.0;","float t = 0.0;","if (dragTexture == 1.0) { "," s = fraction * textureTileFactor.s; "," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","} else { "," s = nodeID / maxTrailLength * textureTileFactor.s;"," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","}","vUV = vec2(s, t); ","gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get TexturedFragmentShader(){return[this.TexturedFragmentVars,"void main() { ","vec4 textureColor = texture2D(trailTexture, vUV);","gl_FragColor = vColor * textureColor;","}"].join("\n")}}}}
|
1
|
+
import*as e from"three";export class Trail extends e.Object3D{constructor(t,r){super(),this.nodeCenters=[],this.nodeIDs=[],this.advance=function(){const t=new e.Matrix4;return function(){this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.advanceWithTransform(t),this.updateUniforms()}}(),this.advanceGeometry=function(e,t){const r=this.currentEnd+1>=this.length?0:this.currentEnd+1;if(t?this.updateNodePositionsFromTransformMatrix(r,t):this.updateNodePositionsFromOrientationTangent(r,e.position,e.tangent),this.currentLength>=1&&(this.connectNodes(this.currentEnd,r),this.currentLength>=this.length)){const e=this.currentEnd+1>=this.length?0:this.currentEnd+1;this.disconnectNodes(e)}this.currentLength<this.length&&this.currentLength++,this.currentEnd++,this.currentEnd>=this.length&&(this.currentEnd=0),this.currentLength>=1&&(this.currentLength<this.length?this.geometry.setDrawRange(0,(this.currentLength-1)*this.FaceIndicesPerNode):this.geometry.setDrawRange(0,this.currentLength*this.FaceIndicesPerNode)),this.updateNodeID(this.currentEnd,this.currentNodeID),this.currentNodeID++},this.updateHead=function(){const t=new e.Matrix4;return function(){this.currentEnd<0||(this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.updateNodePositionsFromTransformMatrix(this.currentEnd,t))}}(),this.updateNodePositionsFromOrientationTangent=function(){const t=new e.Quaternion,r=new e.Vector3,i=[];for(let t=0;t<Trail.MaxHeadVertices;t++){const t=new e.Vector3;i.push(t)}return function(e,a,n){const s=this.geometry.getAttribute("position");this.updateNodeCenter(e,a),r.copy(a),r.sub(Trail.LocalHeadOrigin),t.setFromUnitVectors(Trail.LocalOrientationTangent,n);for(let e=0;e<this.localHeadGeometry.length;e++){const a=i[e];a.copy(this.localHeadGeometry[e]),a.applyQuaternion(t),a.add(r)}for(let t=0;t<this.localHeadGeometry.length;t++){const r=(this.VerticesPerNode*e+t)*Trail.PositionComponentCount,a=i[t];s.array[r]=a.x,s.array[r+1]=a.y,s.array[r+2]=a.z}s.needsUpdate=!0}}(),this.updateNodePositionsFromTransformMatrix=function(){const t=new e.Matrix3,r=new e.Quaternion,i=new e.Vector3,a=new e.Vector3,n=new e.Vector3,s=new e.Vector3,o=[];for(let t=0;t<Trail.MaxHeadVertices;t++){const t=new e.Vector3;o.push(t)}return function(h,c){const l=this.geometry.getAttribute("position");i.set(0,0,0),i.applyMatrix4(c),this.updateNodeCenter(h,i);for(let e=0;e<this.localHeadGeometry.length;e++){o[e].copy(this.localHeadGeometry[e])}for(let e=0;e<this.localHeadGeometry.length;e++){o[e].applyMatrix4(c)}if(this.lastNodeCenter&&this.orientToMovement&&(function(e,t){const r=t.elements;e.set(r[0],r[1],r[2],r[4],r[5],r[6],r[8],r[9],r[10])}(t,c),n.set(0,0,-1),n.applyMatrix3(t),s.copy(this.currentNodeCenter),s.sub(this.lastNodeCenter),s.normalize(),s.lengthSq()<=1e-4&&this.lastOrientationDir&&s.copy(this.lastOrientationDir),s.lengthSq()>1e-4)){this.lastOrientationDir||(this.lastOrientationDir=new e.Vector3),r.setFromUnitVectors(n,s),a.copy(this.currentNodeCenter);for(let e=0;e<this.localHeadGeometry.length;e++){const t=o[e];t.sub(a),t.applyQuaternion(r),t.add(a)}}for(let e=0;e<this.localHeadGeometry.length;e++){const t=(this.VerticesPerNode*h+e)*Trail.PositionComponentCount,r=o[e];l.array[t]=r.x,l.array[t+1]=r.y,l.array[t+2]=r.z}l.needsUpdate=!0,l.addUpdateRange(h*this.VerticesPerNode*Trail.PositionComponentCount,this.VerticesPerNode*Trail.PositionComponentCount)}}(),this.connectNodes=function(){const e={attribute:null,offset:0,count:-1};return function(t,r){const i=this.geometry.getIndex();for(let e=0;e<this.localHeadGeometry.length-1;e++){const a=this.VerticesPerNode*t+e,n=this.VerticesPerNode*r+e,s=(t*this.FacesPerNode+e*Trail.FacesPerQuad)*Trail.IndicesPerFace;i.array[s]=a,i.array[s+1]=n,i.array[s+2]=a+1,i.array[s+3]=n,i.array[s+4]=n+1,i.array[s+5]=a+1}return i.needsUpdate=!0,i.updateRange.count=-1,e.attribute=i,e.offset=t*this.FacesPerNode*Trail.IndicesPerFace,e.count=this.FacesPerNode*Trail.IndicesPerFace,e}}(),this.disconnectNodes=function(){const e={attribute:null,offset:0,count:-1};return function(t){const r=this.geometry.getIndex();for(let e=0;e<this.localHeadGeometry.length-1;e++){const i=(t*this.FacesPerNode+e*Trail.FacesPerQuad)*Trail.IndicesPerFace;r.array[i]=0,r.array[i+1]=0,r.array[i+2]=0,r.array[i+3]=0,r.array[i+4]=0,r.array[i+5]=0}return r.needsUpdate=!0,r.updateRange.count=-1,e.attribute=r,e.offset=t*this.FacesPerNode*Trail.IndicesPerFace,e.count=this.FacesPerNode*Trail.IndicesPerFace,e}}(),this.active=!1,this.orientToMovement=!1,r&&(this.orientToMovement=!0),this.scene=t,this.geometry=null,this.mesh=null,this.nodeCenters=[],this.lastNodeCenter=null,this.currentNodeCenter=null,this.lastOrientationDir=null,this.nodeIDs=[],this.currentLength=0,this.currentEnd=0,this.currentNodeID=0,this.advanceFrequency=60,this.advancePeriod=1/this.advanceFrequency,this.lastAdvanceTime=0,this.paused=!1,this.pauseAdvanceUpdateTimeDiff=0}setAdvanceFrequency(e){this.advanceFrequency=e,this.advancePeriod=1/this.advanceFrequency}initialize(t,r,i,a,n,s){this.deactivate(),this.destroyMesh(),this.length=r>0?r+1:0,this.dragTexture=i?1:0,this.targetObject=s,this.initializeLocalHeadGeometry(a,n),this.nodeIDs=[],this.nodeCenters=[];for(let t=0;t<this.length;t++)this.nodeIDs[t]=-1,this.nodeCenters[t]=new e.Vector3;this.material=t,this.initializeGeometry(),this.initializeMesh(),this.material.uniforms.trailLength.value=0,this.material.uniforms.minID.value=0,this.material.uniforms.maxID.value=0,this.material.uniforms.dragTexture.value=this.dragTexture,this.material.uniforms.maxTrailLength.value=this.length,this.material.uniforms.verticesPerNode.value=this.VerticesPerNode,this.material.uniforms.textureTileFactor.value=new e.Vector2(1,1),this.material.uniforms.scale.value=1,this.reset()}initializeLocalHeadGeometry(t,r){if(this.localHeadGeometry=[],r){this.VerticesPerNode=0;for(let t=0;t<r.length&&t<Trail.MaxHeadVertices;t++){const i=r[t];if(i&&i instanceof e.Vector3){const t=new e.Vector3;t.copy(i),this.localHeadGeometry.push(t),this.VerticesPerNode++}}}else{const r=(t||1)/2;this.localHeadGeometry.push(new e.Vector3(-r,0,0)),this.localHeadGeometry.push(new e.Vector3(r,0,0)),this.VerticesPerNode=2}this.FacesPerNode=2*(this.VerticesPerNode-1),this.FaceIndicesPerNode=3*this.FacesPerNode}initializeGeometry(){this.vertexCount=this.length*this.VerticesPerNode,this.faceCount=this.length*this.FacesPerNode;const t=new e.BufferGeometry,r=new Float32Array(this.vertexCount),i=new Float32Array(this.vertexCount*this.VerticesPerNode),a=new Float32Array(this.vertexCount*Trail.PositionComponentCount),n=new Float32Array(this.vertexCount*Trail.PositionComponentCount),s=new Float32Array(this.vertexCount*Trail.UVComponentCount),o=new Uint32Array(this.faceCount*Trail.IndicesPerFace),h=new e.BufferAttribute(r,1);h.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeID",h);const c=new e.BufferAttribute(i,1);c.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeVertexID",c);const l=new e.BufferAttribute(n,Trail.PositionComponentCount);l.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeCenter",l);const d=new e.BufferAttribute(a,Trail.PositionComponentCount);d.setUsage(e.DynamicDrawUsage),t.setAttribute("position",d);const u=new e.BufferAttribute(s,Trail.UVComponentCount);u.setUsage(e.DynamicDrawUsage),t.setAttribute("uv",u);const m=new e.BufferAttribute(o,1);m.setUsage(e.DynamicDrawUsage),t.setIndex(m),this.geometry=t}zeroVertices(){const e=this.geometry.getAttribute("position");for(let t=0;t<this.vertexCount;t++){const r=3*t;e.array[r]=0,e.array[r+1]=0,e.array[r+2]=0}e.needsUpdate=!0}zeroIndices(){if(null==this.geometry)throw"Geometry not initialized";const e=this.geometry.getIndex();for(let t=0;t<this.faceCount;t++){const r=3*t;e.array[r]=0,e.array[r+1]=0,e.array[r+2]=0}e.needsUpdate=!0,e.addUpdateRange(0,-1)}formInitialFaces(){this.zeroIndices();const e=this.geometry.getIndex();for(let e=0;e<this.length-1;e++)this.connectNodes(e,e+1);e.needsUpdate=!0,e.addUpdateRange(0,-1)}initializeMesh(){if(null==this.geometry)throw"Geometry not initialized";this.mesh=new e.Mesh(this.geometry,this.material),this.mesh.matrixAutoUpdate=!1}destroyMesh(){this.mesh&&(this.scene.remove(this.mesh),this.mesh=null)}reset(){this.currentLength=0,this.currentEnd=-1,this.lastNodeCenter=null,this.currentNodeCenter=null,this.lastOrientationDir=null,this.currentNodeID=0,this.formInitialFaces(),this.zeroVertices(),this.geometry.setDrawRange(0,0)}updateUniforms(){this.currentLength<this.length?this.material.uniforms.minID.value=0:this.material.uniforms.minID.value=this.currentNodeID-this.length,this.material.uniforms.maxID.value=this.currentNodeID,this.material.uniforms.trailLength.value=this.currentLength,this.material.uniforms.maxTrailLength.value=this.length,this.material.uniforms.verticesPerNode.value=this.VerticesPerNode}advanceWithPositionAndOrientation(e,t){this.advanceGeometry({position:e,tangent:t},null)}advanceWithTransform(e){this.advanceGeometry(null,e)}currentTime(){return performance.now()/1e3}pause(){this.paused||(this.paused=!0,this.pauseAdvanceUpdateTimeDiff=this.currentTime()-this.lastAdvanceTime)}resume(){this.paused&&(this.paused=!1,this.lastAdvanceTime=this.currentTime()-this.pauseAdvanceUpdateTimeDiff)}update(){if(!this.paused){const e=this.currentTime();this.lastAdvanceTime||(this.lastAdvanceTime=e),e-this.lastAdvanceTime>this.advancePeriod?(this.advance(),this.lastAdvanceTime=e):this.updateHead()}}updateNodeID(e,t){this.nodeIDs[e]=t;const r=this.geometry.getAttribute("nodeID"),i=this.geometry.getAttribute("nodeVertexID");for(let a=0;a<this.VerticesPerNode;a++){const n=e*this.VerticesPerNode+a;r.array[n]=t,i.array[n]=a}r.needsUpdate=!0,i.needsUpdate=!0,r.addUpdateRange(e*this.VerticesPerNode,this.VerticesPerNode),i.addUpdateRange(e*this.VerticesPerNode,this.VerticesPerNode)}updateNodeCenter(e,t){this.lastNodeCenter=this.currentNodeCenter,this.currentNodeCenter=this.nodeCenters[e],this.currentNodeCenter.copy(t);const r=this.geometry.getAttribute("nodeCenter");for(let i=0;i<this.VerticesPerNode;i++){const a=3*(e*this.VerticesPerNode+i);r.array[a]=t.x,r.array[a+1]=t.y,r.array[a+2]=t.z}r.needsUpdate=!0,r.updateRanges=[{start:e*this.VerticesPerNode*Trail.PositionComponentCount,count:this.VerticesPerNode*Trail.PositionComponentCount}]}deactivate(){this.active&&(this.scene.remove(this.mesh),this.active=!1)}activate(){this.active||(this.scene.add(this.mesh),this.active=!0)}static createMaterial(t,r,i){return(i=i||{}).trailLength={type:"f",value:null},i.verticesPerNode={type:"f",value:null},i.minID={type:"f",value:null},i.maxID={type:"f",value:null},i.dragTexture={type:"f",value:null},i.maxTrailLength={type:"f",value:null},i.textureTileFactor={type:"v2",value:null},i.headColor={type:"v4",value:new e.Vector4},i.tailColor={type:"v4",value:new e.Vector4},i.taper={type:"bool",value:!1},i.scale={type:"f",value:1},t=t||Trail.Shader.BaseVertexShader,r=r||Trail.Shader.BaseFragmentShader,new e.ShaderMaterial({uniforms:i,vertexShader:t,fragmentShader:r,transparent:!0,alphaTest:.5,blending:e.CustomBlending,blendSrc:e.SrcAlphaFactor,blendDst:e.OneMinusSrcAlphaFactor,blendEquation:e.AddEquation,depthTest:!0,depthWrite:!1,side:e.DoubleSide})}static createBaseMaterial(e={}){return Trail.createMaterial(Trail.Shader.BaseVertexShader,Trail.Shader.BaseFragmentShader,e)}static createTexturedMaterial(e){return(e={}).trailTexture={type:"t",value:null},Trail.createMaterial(Trail.Shader.TexturedVertexShader,Trail.Shader.TexturedFragmentShader,e)}static get MaxHeadVertices(){return 128}static{this._LocalOrientationTangent=new e.Vector3(1,0,0)}static get LocalOrientationTangent(){return Trail._LocalOrientationTangent}static{this._LocalHeadOrigin=new e.Vector3(0,0,0)}static get LocalHeadOrigin(){return Trail._LocalHeadOrigin}static get PositionComponentCount(){return 3}static get UVComponentCount(){return 2}static get IndicesPerFace(){return 3}static get FacesPerQuad(){return 2}static{this.Shader={get BaseVertexVars(){return["attribute float nodeID;","attribute float nodeVertexID;","attribute vec3 nodeCenter;","uniform float minID;","uniform float maxID;","uniform float trailLength;","uniform float maxTrailLength;","uniform float verticesPerNode;","uniform vec2 textureTileFactor;","uniform bool taper;","uniform vec4 headColor;","uniform vec4 tailColor;","varying vec4 vColor;"].join("\n")},get TexturedVertexVars(){return[this.BaseVertexVars,"varying vec2 vUV;","uniform float dragTexture;"].join("\n")},BaseFragmentVars:["varying vec4 vColor;","uniform sampler2D trailTexture;"].join("\n"),get TexturedFragmentVars(){return[this.BaseFragmentVars,"varying vec2 vUV;"].join("\n")},get VertexShaderCore(){return["float fraction = (maxID - nodeID) / (maxID - minID);","float fractionSize = taper ? fraction : 0.0;","vColor = (1.0 - fraction) * headColor + fraction * tailColor;","vec4 realPosition = vec4((1.0 - fractionSize) * position.xyz + fractionSize * nodeCenter.xyz, 1.0); "].join("\n")},get BaseVertexShader(){return[this.BaseVertexVars,"void main() { ",this.VertexShaderCore,"gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get BaseFragmentShader(){return[this.BaseFragmentVars,"void main() { ","gl_FragColor = vColor;","}"].join("\n")},get TexturedVertexShader(){return[this.TexturedVertexVars,"void main() { ",this.VertexShaderCore,"float s = 0.0;","float t = 0.0;","if (dragTexture == 1.0) { "," s = fraction * textureTileFactor.s; "," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","} else { "," s = nodeID / maxTrailLength * textureTileFactor.s;"," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","}","vUV = vec2(s, t); ","gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get TexturedFragmentShader(){return[this.TexturedFragmentVars,"void main() { ","vec4 textureColor = texture2D(trailTexture, vUV);","gl_FragColor = vColor * textureColor;","}"].join("\n")}}}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
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}}
|
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{AttributeVec3Node as a,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as m,UniformVec3Node as u,Vec3ExpressionNode as p,Vec4Node as d,attributeFloat as h,attributeVec3 as f,attributeVec4 as g,attributes as w,float as y,glslFunction as A,lambertMaterial as v,log as x,pow as E,rgba as b,saturate as P,textureSampler2d as M,transformed as I,uniforms as R,varyingAttributes as z,varyingVec3 as V,varyingVec4 as B}from"three-shader-graph";import{prepareShapeParameters as T}from"../../scene/materializer.js";import{ShapeLibrary as S}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as j,linearEyeDepth as k}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as C,particleVelcoityUniformName as F}from"../../shader-nodes/particle.js";import{DefaultInitializer as Q}from"./initializsers.js";import{DelayRate as U,OnceRate as H}from"./rates.js";import{ThreeBlendingMode as D}from"./vfx-asset.js";import{VfxBehaviourLibrary as G,VfxInitializserLibrary as J}from"./vfx-defs.js";import{MultiRenderer as q}from"./vfx-renderers.js";import{StretchedSprite as W}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 q(c,l,t,r),u=new i;return(await Promise.all(n.vfx.emitters.map((async t=>{const e=await L(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 L(i,n,s){const m=function(t){let e;switch(t.rate.type){case"continuous":e=new U(t.rate.delay??0,t.rate.count,t.rate.time);break;case"once":e=new H(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 C;switch(i.output.type){case"sprite":C=new o(await async function(e,i){const n=null!=e.texture?await i.getTexture(e.texture):N,o=M(n).sample(z.uv),s=new u("color").rgb,r=(new u("opacity").rgb,k.subtract(j).divide(k));let a=o.x;if("number"==typeof e.softness&&e.softness>0){const t=E(r,y(e.softness));a=a.multiply(t)}const l=A(d,{position:I.position,modelViewMatrix:R.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 K({color:b(s,a).multiply(o),transparent:!0,position:l,uniforms:{color:{value:new t.Color(e.color)}}});c.blending=D[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":C=new o(await async function(e,i){const n=null!=e.texture?await i.getTexture(e.texture):N,o=M(n).sample(z.uv),s=B(new l("color")),r=s.rgb;let a=s.w;if("number"==typeof e.softness&&e.softness>0){const t=k.subtract(j).divide(x(k)),i=E(t,y(e.softness));a=P(a.multiply(i))}const c=A(d,{position:w.position,offset:g("offset"),modelViewMatrix:R.modelViewMatrix,velocity:g("velocity"),size:f("size"),rotation:h("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 m=new K({color:b(r,a).multiply(o),transparent:!0,position:c,uniforms:{}});m.blending=D[e.blendingMode]??t.NormalBlending;const u=new W(new t.PlaneGeometry(1,1),m);return u.scaleFactor=e.scale,u}(i.output,n));break;case"shape":C=new o(await async function(i,n){const o=S[i.shape];if(null==o)return console.error(`No shape with type ${i.shape}`),new e;const s=T(i.params??{}),r=o.geometry(s),l=null!=i.material?await n.getMaterial(i.material):function(){const t=V(new p("instanceColor")).rgb,e=V(new a("particleData")).x;return new c({color:v({color:t}).rgb.rgba(e),transparent:!0})}();return new t.Mesh(r,l)}(i.output,n));break;case"mesh":C=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":C=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 F=new X;F.parent=s,F.setRate(m),F._space=i.output.space;const q=await Promise.all(i.initializers.filter((t=>null!=J[t.type])).map((async t=>{const e=J[t.type],i=await T(t.params??{});return e.build(i)})));q.push(C,new Q),F.addInitializers(q);const Y=await Promise.all(i.behaviours.filter((t=>null!=G[t.type])).map((async t=>{const e=G[t.type],i=await T(t.params??{});return e.build(i)})));Y.push(new O),F.addBehaviours(Y);for(const t of i.children){const e=await L(t,n,s),i=new EmitterPool((()=>{const t=e.clone();return t.onExpired=()=>{const e=F.childEmitters.findIndex((e=>e.id===t.id));-1!=e&&F.childEmitters.splice(e,1),i.release(t)},t})),o=F.eventDispatcher,r=new Map;F.bindEmitterEvent=!0,o.addEventListener("PARTICLE_DEAD",(t=>{const e=r.get(t.id);if(null!=e){const t=F.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,F.childEmitters.push(e),r.set(t.id,e),e.parentParticle=t,e.emit()}))}return F}const N=(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 K extends c{get color(){return this.uniforms.color.value}set color(e){this.uniforms.color.value=new t.Color(e)}}class O extends n{initialize(e){if(e.body instanceof t.Mesh){const t=e.body.material;t instanceof c&&(null!=t.uniforms[C]||null!=t.uniforms[F])&&(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 c&&(null!=t.uniforms[C]&&(t.uniforms[C].value=this.energy),null!=t.uniforms[F]&&(t.uniforms[F].value=e.velocity))}}}class X 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 X;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.
|
@@ -1,11 +1,5 @@
|
|
1
1
|
import { BaseActor } from '../actor.js';
|
2
2
|
import { CameraComponent } from '../camera/camera-component.js';
|
3
|
-
import { ActorComponent } from '../component.js';
|
4
|
-
export declare class CameraMesh extends ActorComponent {
|
5
|
-
private arrowColor;
|
6
|
-
onInit(): void | Promise<void>;
|
7
|
-
}
|
8
3
|
export declare class CameraActor extends BaseActor {
|
9
4
|
camera: CameraComponent;
|
10
|
-
private mesh;
|
11
5
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as
|
1
|
+
import{__decorate as o}from"tslib";import{Actor as r,BaseActor as t}from"../actor.js";import{CameraComponent as m}from"../camera/camera-component.js";import{attach as e}from"../component.js";let s=class extends t{constructor(){super(...arguments),this.camera=e(m)}};s=o([r()],s);export{s as CameraActor};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,13 +1,18 @@
|
|
1
|
-
import { ActorComponent } from '../component.js';
|
2
|
-
import { ViewController } from '../../services/render.js';
|
3
1
|
import { PerspectiveCamera } from 'three';
|
2
|
+
import { ViewController } from '../../services/render.js';
|
3
|
+
import { ActorComponent } from '../component.js';
|
4
4
|
export declare class CameraComponent extends ActorComponent {
|
5
5
|
private viewController;
|
6
6
|
near: number;
|
7
7
|
far: number;
|
8
8
|
viewAngle: number;
|
9
|
+
private debugMesh;
|
9
10
|
private aspect;
|
10
11
|
instance: PerspectiveCamera;
|
11
12
|
constructor(viewController: ViewController);
|
12
13
|
onInit(): void | Promise<void>;
|
13
14
|
}
|
15
|
+
export declare class CameraMesh extends ActorComponent {
|
16
|
+
private arrowColor;
|
17
|
+
onInit(): void | Promise<void>;
|
18
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{ArrowHelper as r,ConeGeometry as i,EdgesGeometry as s,LineBasicMaterial as o,LineSegments as n,MeshStandardMaterial as a,PerspectiveCamera as l,Vector3 as h}from"three";import{Parameter as d}from"../../../shader/parameter.js";import{ViewController as c}from"../../services/render.js";import{ActorComponent as p,attach as w,Component as m}from"../component.js";const v=void 0!==window&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let b=class extends p{constructor(e){super(),this.viewController=e,this.near=.5,this.far=500,this.viewAngle=v?30:45,this.debugMesh=w(y),this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.instance=new l(this.viewAngle,this.aspect,this.near,this.far)}onInit(){this.actor.object.add(this.instance),this.instance.near=this.near,this.instance.far=this.far,this.instance.fov=this.viewAngle}};e([d(),t("design:type",Number)],b.prototype,"near",void 0),e([d(),t("design:type",Number)],b.prototype,"far",void 0),e([d(),t("design:type",Number)],b.prototype,"viewAngle",void 0),b=e([m({inEditor:!0}),t("design:paramtypes",[c])],b);export{b as CameraComponent};let y=class extends p{constructor(){super(...arguments),this.arrowColor=16101442}onInit(){const e=new i(1,1,4);e.rotateX(Math.PI/2),e.rotateZ(Math.PI/4),e.scale(1,9/16,1);const t=new s(e),l=(new a({color:3355443}),new n(t,new o({color:16777215}))),d=new r(new h(0,0,-1),new h(0,0,0),1.2,this.arrowColor,.15,.2);l.add(d),d.layers.disableAll(),d.layers.enable(19),d.traverse((e=>{e.layers.disableAll(),e.layers.enable(19)})),this.actor.object.add(l)}};y=e([m({inEditor:!0,editorOnly:!0})],y);export{y as CameraMesh};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -19,6 +19,10 @@ export type InitiateGameConfig = {
|
|
19
19
|
rendering?: Partial<{
|
20
20
|
resolutionScale: number;
|
21
21
|
maxPixelRatio: number;
|
22
|
+
shadows: {
|
23
|
+
enabled?: boolean;
|
24
|
+
autoUpdate?: boolean;
|
25
|
+
};
|
22
26
|
}>;
|
23
27
|
};
|
24
28
|
export declare function initiateGame<T_Game>(gameClass: GameClass<T_Game>, config: InitiateGameConfig): HologyRuntime<T_Game>;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as n}from"./actors/factory.js";import{World as s}from"./services/world.js";import{ViewController as o}from"./services/render.js";import{RenderingView as r}from"../rendering.js";import{PhysicsSystem as i}from"./services/physics/physics-system.js";import{MeshComponent as a}from"./actors/builtin/components/mesh-component.js";import{activeContainerInstance as c}from"./actors/internal/container-map.js";import{InputService as m}from"./input/index.js";import{RuntimeAssetsService as
|
1
|
+
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as n}from"./actors/factory.js";import{World as s}from"./services/world.js";import{ViewController as o}from"./services/render.js";import{RenderingView as r}from"../rendering.js";import{PhysicsSystem as i}from"./services/physics/physics-system.js";import{MeshComponent as a}from"./actors/builtin/components/mesh-component.js";import{activeContainerInstance as c}from"./actors/internal/container-map.js";import{InputService as m}from"./input/index.js";import{RuntimeAssetsService as d}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as l}from"../scene/asset-resource-loader.js";import{AssetLoader as p}from"./services/asset-loader.js";import{polyfillClient as h}from"./polyfill.js";import{Subject as u}from"rxjs";import{PointerEvents as f}from"./services/pointer-events.js";import{RuntimeBundledBackendService as w}from"../scene/runtime-bundled-backend-service.js";export function initiateGame(m,u){if(h(),0!=u.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(o);const g=e.of("default"),j=new HologyRuntime(g),v=new n(g,{inEditor:!1});var S;e.set(n,v),S=u.element,Object.assign(S.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const y=new r(u.element,{enableXR:!0===u.xr?.enabled,maxPixelRatio:u.rendering?.maxPixelRatio});y.renderer.shadowMap.enabled=u.rendering?.shadows?.enabled??!0,y.renderer.shadowMap.autoUpdate=u.rendering?.shadows?.autoUpdate??!0,null!=u?.rendering?.resolutionScale&&(y.resolutionScale=u.rendering.resolutionScale),e.set(r,y);const I=new o(y);e.set(o,I);const x=e.get(s);e.set(s,x);const b=new w,D=new d(b),R=new l;R.setDataDir(u.dataDir);const G=Object.entries(u.shaders).map((([e,t])=>({name:e,type:t}))),H=new p(R,D,G);return e.set(p,H),(async()=>{const n=e.get(i);if(await n.start(),j.isShutdown)return;if(await b.preloadData(),j.isShutdown)return;const{scene:s,actors:o}=await t(y,u.sceneName,u.dataDir,u.shaders,u.actors,v,b,D,R);if(x.scene=s,j.isShutdown)return void y.stop();e.import([a]);for(const e of o)x.addActor(e);n.addFromScene(s),y.loop((e=>{})),j.status=5,c.value=g,g.remove(m),g.set({id:m,type:m});const r=g.get(m);c.value=null,j.gameInstance=r,g.get(f).start(),r instanceof GameInstance&&r.onStart(),j._resolver(!0)})(),j}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new u,this.ready=new Promise((e=>{this._resolver=e}))}getWorld(){return this.containerInstance.get(s)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0,this.shutdownStarted.next(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(m).stop();const e=this.containerInstance.get(r);e?.stop();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(i).stop(),this.containerInstance.get(f).stop(),this.containerInstance.reset()}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -17,6 +17,7 @@ export declare class AssetLoader {
|
|
17
17
|
private objLoader;
|
18
18
|
private mtlLoader;
|
19
19
|
private tgaLoader;
|
20
|
+
private ktx2Loader;
|
20
21
|
private textureLoader;
|
21
22
|
private audioLoader;
|
22
23
|
constructor(assetResourceLoader: AssetResourceLoader, assetService: AssetsProvider, shaders: ShaderImpl[]);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{AssetResourceLoader as s}from"../../scene/asset-resource-loader.js";import{FBXLoader as r,GLTFLoader as a,MTLLoader as o,OBJLoader as i,TGALoader as n}from"three-stdlib";import{AudioLoader as d,LoadingManager as h,TextureLoader as l}from"three";import{pathJoin as u}from"../../utils/files.js";import{Service as c}from"typedi";import{materialFromAsset as g}from"../../scene/materializer.js";let
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{AssetResourceLoader as s}from"../../scene/asset-resource-loader.js";import{FBXLoader as r,GLTFLoader as a,MTLLoader as o,OBJLoader as i,TGALoader as n}from"three-stdlib";import{AudioLoader as d,LoadingManager as h,TextureLoader as l}from"three";import{pathJoin as u}from"../../utils/files.js";import{Service as c}from"typedi";import{materialFromAsset as g}from"../../scene/materializer.js";import{KTX2Loader as w}from"three/examples/jsm/Addons.js";let f=class{constructor(e,t,s){this.assetResourceLoader=e,this.assetService=t,this.shaders=s,this.baseUrl="",this.urlSuffix="",this.loadingManager=new h,this.glbLoader=new a(this.loadingManager),this.fbxLoader=new r(this.loadingManager),this.objLoader=new i(this.loadingManager),this.mtlLoader=new o(this.loadingManager),this.tgaLoader=new n(this.loadingManager),this.ktx2Loader=new w(this.loadingManager),this.textureLoader=new l(this.loadingManager),this.audioLoader=new d(this.loadingManager)}resolvePath(e){return u(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find((t=>t.name===e));if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t)}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return g(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}};f=e([c(),t("design:paramtypes",[s,Object,Array])],f);export{f as AssetLoader};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as 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]];
|
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){if(null==i){console.warn("Collision shape is missing for object",t);continue}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.
|
package/dist/rendering.d.ts
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
import * as THREE from "three";
|
2
|
-
import {
|
2
|
+
import { Camera, Object3D, WebGLRenderer, WebGLRenderTarget } from "three";
|
3
3
|
import { CSM } from "three/examples/jsm/csm/CSM.js";
|
4
4
|
export type RenderingViewOptions = {
|
5
5
|
enableOutlines?: boolean;
|
6
6
|
enableXR?: boolean;
|
7
7
|
maxPixelRatio?: number;
|
8
|
+
shadows?: {
|
9
|
+
autoUpdate?: boolean;
|
10
|
+
};
|
8
11
|
};
|
9
12
|
export declare class RenderingView {
|
10
13
|
container: HTMLElement;
|
@@ -32,6 +35,7 @@ export declare class RenderingView {
|
|
32
35
|
private onVisiblityChane;
|
33
36
|
private isDepthTextureExtensionSupported;
|
34
37
|
constructor(container: HTMLElement, options?: RenderingViewOptions);
|
38
|
+
private fixStatsStyle;
|
35
39
|
setCamera(camera: Camera): void;
|
36
40
|
setSelectedObjects(obj: Object3D[]): void;
|
37
41
|
private static createDepthRenderTarget;
|
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,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;
|
1
|
+
var e;import{__decorate as t,__metadata as i}from"tslib";import*as s from"three";import{Color as r,Material as n,Matrix4 as a,Mesh as o,PerspectiveCamera as h,ShaderChunk as l,ShaderMaterial as d}from"three";import{EffectComposer as c,FXAAShader as m,GammaCorrectionShader as p,RenderPass as u,ShaderPass as g,UnrealBloomPass as f,VRButton as v}from"three-stdlib";import{CSMShader as w,CSMUtil as x}from"./csm.js";import*as b from"stats.js";import{Reflector as C}from"three-stdlib";import{CSM as S}from"three/examples/jsm/csm/CSM.js";import{Service as y}from"typedi";import{depthUniformName as P,farUniformName as R,nearUniformName as M,resolutionUniformName as T,supportsDepthTextureExtension as W}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as E}from"./shader-nodes/time.js";import{DepthPass as L}from"./utils/three/depth-pass.js";import{GPUStatsPanel as H}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as B}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as D}from"./utils/three/traverse.js";(new s.Layers).set(9);const F=new s.MeshBasicMaterial({color:"black"}),V=new s.MeshDepthMaterial;V.depthPacking=s.RGBADepthPacking,V.blending=s.NoBlending;const j=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let k=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=new b,this._showStats=!0,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 r,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(v.createButton(this.renderer)),this.composer=new c(this.renderer);var n=t.clientWidth/t.clientHeight;const a=new s.PerspectiveCamera(45,n,.5,800);a.layers.enable(19),this.setCamera(a),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=s.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=i.shadows?.autoUpdate??!1,this.renderer.outputColorSpace=s.SRGBColorSpace,this.renderer.toneMapping=s.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,x.renderingView=this,x.patchThreeAdd(),this.isDepthTextureExtensionSupported=W(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=e.createDepthRenderTarget(this.renderer,this.container);const o=new u(this.scene,this.camera);this.composer.addPass(o);const h=new f(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 c(this.renderer);l.renderToScreen=!1,l.addPass(o),l.addPass(h),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 B(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(m);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var w=new g(p);w.clear=!1,this.composer.addPass(w),this.fixStatsStyle()}fixStatsStyle(){const e=this.stats.dom;e.style.position="absolute";const t=e.getElementsByTagName("canvas");for(let e=0;e<t.length;e++)t.item(e).style.display="inline-block"}setCamera(e){this.camera=e,this.composer.passes.forEach((t=>{t instanceof u?t.camera=e:t instanceof B?t.renderCamera=e:t instanceof L&&(t.camera=e)})),null==this.csm?(this.csm=new S({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"}),l.lights_fragment_begin=w.lights_fragment_begin):(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);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,r=i.addPanel(new b.Panel("Calls","#83f","#002"));let h;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(h=new H(this.renderer.getContext()),i.addPanel(h)),this.showStats=t;let l=10;const d=()=>{const e=this.renderer.info.render.calls;e>l&&(l=e,setTimeout((()=>l=10),5e3)),r.update(e,l)};performance.now();s.Ray.prototype.intersectTriangle;const c=[],m=[];let p=0;const u=new a,g=new a,f=t=>{const r=this.renderer.getContext();if(this.paused&&this.running&&r.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 a=(t*=.001)-p;if(p=t,u.copy(this.camera.matrixWorld),a>1){let t=a;for(;t>.05;)e(z),t-=z;e(t)}else e(a);if(this.onLoopCallbacks.forEach((e=>e(a))),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 o||e instanceof s.Sprite)&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[P])?(e.visible=!1,c.push(e),this.initDepthUniform(e.material),e.renderOrder=100):(e instanceof C||(e instanceof o||e instanceof s.Sprite)&&function(e){if(e.material instanceof n)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 o&&e.material?.uniforms&&null!=e.material?.uniforms[E]&&(e.material.uniforms[E].value=t)})),c.length>0){if(this.scene.overrideMaterial=V,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(a),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!=D(this.scene,(e=>e instanceof o&&!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 d&&(e.uniforms[P].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[T]&&e.uniforms[T].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof h&&(e.uniforms[M].value=this.camera.near,e.uniforms[R].value=this.camera.far))}};k=e=t([y(),i("design:paramtypes",[HTMLElement,Object])],k);export{k as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const z=.05;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -12,6 +12,8 @@ export declare class AssetResourceLoader {
|
|
12
12
|
private fbxLoader;
|
13
13
|
private objLoader;
|
14
14
|
private textureLoader;
|
15
|
+
private tgaLoader;
|
16
|
+
private ktx2Loader;
|
15
17
|
private _textureLoader;
|
16
18
|
private audioLoader;
|
17
19
|
protected onError(error: unknown): void;
|
@@ -21,6 +23,7 @@ export declare class AssetResourceLoader {
|
|
21
23
|
setDataDir(path: string): void;
|
22
24
|
private getUri;
|
23
25
|
getTexture(asset: Asset): Promise<Texture>;
|
26
|
+
private _getTextureLoader;
|
24
27
|
getMesh(asset: Asset): Promise<LoadedMesh>;
|
25
28
|
getAudio(asset: Asset): Promise<AudioBuffer>;
|
26
29
|
private collisionShapeCache;
|
@@ -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
|
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 l}from"three-stdlib";import{cloneMesh as c}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as m,firstValueFrom as p}from"rxjs";import{importCollisionShapes as g}from"./collision/collision-shape-import.js";import*as u from"three";import{iterateMaterials as f}from"../utils/materials.js";import{KTX2Loader as w,TGALoader as y}from"three/examples/jsm/Addons.js";const L=["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 l(this.loadingManager),this.objLoader=new h(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.tgaLoader=new y(this.loadingManager),this.ktx2Loader=new w(this.loadingManager),this._textureLoader=new u.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._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then((t=>(t.wrapS=b(e.texture?.wrapS),t.wrapT=b(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0,this.textureCache.set(e.id,t),t))),this.textureCache.get(e.id))}_getTextureLoader(e){return e.toLowerCase().endsWith(".tga")?this.tgaLoader:e.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:this.textureLoader}async getMesh(e){if(await this.ready,!L.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=c(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,g(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=>{M.test(e.name)&&(a=!0)})),!a)return t;const s=new u.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(M);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=>(x(e),e))).then((e=>({scene:e,animations:e.animations})))}}}function x(e){if(e instanceof s)for(const t of f(e.material))t instanceof u.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(x)}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 b(e){switch(e){case"clamp":return u.ClampToEdgeWrapping;case"repeat":return u.RepeatWrapping;case"mirror":return u.MirroredRepeatWrapping}return u.RepeatWrapping}const M=/_LOD(\d+)$/;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{Group as e,Mesh as a}from"three";import{Color as r}from"three";import{varyingAttributes as t,float as n,mod as o,dot as s,vec2 as c,step as i,fract as l,mix as p,rgb as d,NodeShaderMaterial as u,rgba as m,standardMaterial as f}from"three-shader-graph";import{mixColorsByLayer as L,select as h}from"../../shader-nodes/index.js";export function initLandscape(e){e.sections.y,e.sectionSize,e.sections.x,e.sectionSize;return new LandscapeGroup}export function createLandscapeDefaultMaterial(){const e=t.uv,a=n(10),h=n(7),x=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(a)))),n(2)),S=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(h.multiply(a))))),n(2)),w=p(d(new r(4473924).convertLinearToSRGB()),d(new r(5592405).convertLinearToSRGB()),x),v=p(w,w.addScalar(n(.1)),S),y=L({layerColors:[m(v).rgb
|
1
|
+
import{Group as e,Mesh as a}from"three";import{Color as r}from"three";import{varyingAttributes as t,float as n,mod as o,dot as s,vec2 as c,step as i,fract as l,mix as p,rgb as d,NodeShaderMaterial as u,rgba as m,standardMaterial as f}from"three-shader-graph";import{mixColorsByLayer as L,select as h}from"../../shader-nodes/index.js";export function initLandscape(e){e.sections.y,e.sectionSize,e.sections.x,e.sectionSize;return new LandscapeGroup}export function createLandscapeDefaultMaterial(){const e=t.uv,a=n(10),h=n(7),x=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(a)))),n(2)),S=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(h.multiply(a))))),n(2)),w=p(d(new r(4473924).convertLinearToSRGB()),d(new r(5592405).convertLinearToSRGB()),x),v=p(w,w.addScalar(n(.1)),S),y=L({layerColors:[m(v).rgb,...["#55DDE0","#33658A","#2F4858"].map((e=>new r(e).convertLinearToSRGB())).map((e=>d(e))).reverse()],enableNoise:!1}),D=new u({color:f({color:y})});return D.color=new r("#aaaaaa"),D.name="Default",D}export const defaultLandscapeMaterial=createLandscapeDefaultMaterial();export class LandscapeMesh extends a{}export class LandscapeGroup extends e{get sections(){return this.children.filter((e=>e instanceof LandscapeMesh))}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|