@adatechnology/game-fluids-three 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.global.js +205 -88
- package/dist/index.global.js.map +1 -1
- package/package.json +5 -5
package/dist/index.global.js
CHANGED
|
@@ -6358,6 +6358,24 @@ var GameFluidsThree = (() => {
|
|
|
6358
6358
|
for (const decal2 of this.decals) decal2.on = false;
|
|
6359
6359
|
this.count = 0;
|
|
6360
6360
|
}
|
|
6361
|
+
/**
|
|
6362
|
+
* Takes away the marks inside a box: world `center`, `half` extents along the axes of the world `rotation` (a quaternion, x y z w; none means the
|
|
6363
|
+
* world axes). The surface they were on is gone (a brick came out of a wall with its bullet holes). Returns how many went.
|
|
6364
|
+
*/
|
|
6365
|
+
clearInside(center, half, rotation = [0, 0, 0, 1]) {
|
|
6366
|
+
const qx = -rotation[0], qy = -rotation[1], qz = -rotation[2], qw = rotation[3];
|
|
6367
|
+
let gone = 0;
|
|
6368
|
+
for (const decal2 of this.decals) {
|
|
6369
|
+
if (!decal2.on) continue;
|
|
6370
|
+
const vx2 = decal2.x - center[0], vy2 = decal2.y - center[1], vz2 = decal2.z - center[2];
|
|
6371
|
+
const tx = 2 * (qy * vz2 - qz * vy2), ty = 2 * (qz * vx2 - qx * vz2), tz = 2 * (qx * vy2 - qy * vx2);
|
|
6372
|
+
const lx = vx2 + qw * tx + (qy * tz - qz * ty), ly = vy2 + qw * ty + (qz * tx - qx * tz), lz = vz2 + qw * tz + (qx * ty - qy * tx);
|
|
6373
|
+
if (Math.abs(lx) > half[0] || Math.abs(ly) > half[1] || Math.abs(lz) > half[2]) continue;
|
|
6374
|
+
decal2.on = false;
|
|
6375
|
+
gone++;
|
|
6376
|
+
}
|
|
6377
|
+
return gone;
|
|
6378
|
+
}
|
|
6361
6379
|
update(dt) {
|
|
6362
6380
|
this.count = 0;
|
|
6363
6381
|
for (const decal2 of this.decals) {
|
|
@@ -7670,6 +7688,11 @@ void main(){
|
|
|
7670
7688
|
var MAX_CONFORM_STEPS = 48;
|
|
7671
7689
|
var MIN_CONFORM_STEPS = 16;
|
|
7672
7690
|
var BLOOD_GROW_RATE = 1.2;
|
|
7691
|
+
var BLOOD_START_GROWTH = 0.05;
|
|
7692
|
+
var DEFAULT_MAX_GROUND_MARKS = 64;
|
|
7693
|
+
var DEFAULT_MAX_ROCKS = 512;
|
|
7694
|
+
var DEFAULT_MAX_BLOOD = 256;
|
|
7695
|
+
var MAX_SPARE_GROUND_GEOMETRIES = 16;
|
|
7673
7696
|
function createMarkLayer(THREE, options) {
|
|
7674
7697
|
const group = new THREE.Group();
|
|
7675
7698
|
const textures = createMarkTextures(THREE, options.createCanvas);
|
|
@@ -7693,110 +7716,168 @@ void main(){
|
|
|
7693
7716
|
const bloodMaterial = new THREE.MeshStandardMaterial({ color: 6031882, roughness: 0.15, metalness: 0.1, polygonOffset: true, polygonOffsetFactor: -3, polygonOffsetUnits: -3 });
|
|
7694
7717
|
const bloodGeometry = new THREE.CircleGeometry(0.5, 9).rotateX(-Math.PI / 2);
|
|
7695
7718
|
owned.push(bloodMaterial, bloodGeometry);
|
|
7696
|
-
const
|
|
7697
|
-
const
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
material = new THREE.MeshStandardMaterial({ color, roughness: 0.9, metalness: 0, flatShading: true });
|
|
7703
|
-
rockMaterials.set(color, material);
|
|
7704
|
-
owned.push(material);
|
|
7719
|
+
const maxGroundMarks = options.maxGroundMarks ?? DEFAULT_MAX_GROUND_MARKS;
|
|
7720
|
+
const instanced = {};
|
|
7721
|
+
function rockMaterial() {
|
|
7722
|
+
if (!instanced.rockMaterial) {
|
|
7723
|
+
instanced.rockMaterial = new THREE.MeshStandardMaterial({ color: 16777215, roughness: 0.9, metalness: 0, flatShading: true });
|
|
7724
|
+
owned.push(instanced.rockMaterial);
|
|
7705
7725
|
}
|
|
7706
|
-
return
|
|
7726
|
+
return instanced.rockMaterial;
|
|
7727
|
+
}
|
|
7728
|
+
function bloodMesh() {
|
|
7729
|
+
return instanced.blood ?? (instanced.blood = attach(createInstanced(bloodGeometry, bloodMaterial, options.maxBlood ?? DEFAULT_MAX_BLOOD)));
|
|
7730
|
+
}
|
|
7731
|
+
function rockMesh() {
|
|
7732
|
+
return instanced.rock ?? (instanced.rock = attach(createInstanced(options.rockGeometry, rockMaterial(), options.maxRocks ?? DEFAULT_MAX_ROCKS), true));
|
|
7733
|
+
}
|
|
7734
|
+
function plateMesh() {
|
|
7735
|
+
return instanced.plate ?? (instanced.plate = attach(createInstanced(options.plateGeometry, rockMaterial(), options.maxRocks ?? DEFAULT_MAX_ROCKS), true));
|
|
7736
|
+
}
|
|
7737
|
+
function attach(mesh2, castShadow = false) {
|
|
7738
|
+
mesh2.castShadow = castShadow;
|
|
7739
|
+
group.add(mesh2);
|
|
7740
|
+
return mesh2;
|
|
7741
|
+
}
|
|
7742
|
+
const groundMarks = [];
|
|
7743
|
+
const spareGeometries = [];
|
|
7744
|
+
const blood = [];
|
|
7745
|
+
const placed = { blood: 0, rock: 0, plate: 0 };
|
|
7746
|
+
const matrix = new THREE.Matrix4();
|
|
7747
|
+
const position = new THREE.Vector3();
|
|
7748
|
+
const quaternion = new THREE.Quaternion();
|
|
7749
|
+
const euler = new THREE.Euler();
|
|
7750
|
+
const scale2 = new THREE.Vector3();
|
|
7751
|
+
const color = new THREE.Color();
|
|
7752
|
+
const up = new THREE.Vector3(0, 1, 0);
|
|
7753
|
+
function createInstanced(geometry, material, capacity) {
|
|
7754
|
+
const mesh2 = new THREE.InstancedMesh(geometry, material, capacity);
|
|
7755
|
+
mesh2.count = 0;
|
|
7756
|
+
mesh2.frustumCulled = false;
|
|
7757
|
+
mesh2.receiveShadow = true;
|
|
7758
|
+
return mesh2;
|
|
7759
|
+
}
|
|
7760
|
+
function takeSpare(vertexCount) {
|
|
7761
|
+
const found = spareGeometries.findIndex((geometry) => geometry.getAttribute("position").count === vertexCount);
|
|
7762
|
+
return found < 0 ? void 0 : spareGeometries.splice(found, 1)[0];
|
|
7763
|
+
}
|
|
7764
|
+
function evictOldestGroundMark() {
|
|
7765
|
+
const oldest = groundMarks.shift();
|
|
7766
|
+
group.remove(oldest.mesh);
|
|
7767
|
+
spareGeometries.push(oldest.mesh.geometry);
|
|
7768
|
+
if (spareGeometries.length > MAX_SPARE_GROUND_GEOMETRIES) spareGeometries.shift().dispose();
|
|
7707
7769
|
}
|
|
7708
7770
|
function conform(mark, material) {
|
|
7709
7771
|
const radius = mark.radius;
|
|
7710
7772
|
const steps = Math.max(MIN_CONFORM_STEPS, Math.min(MAX_CONFORM_STEPS, Math.round(radius * 8)));
|
|
7711
|
-
|
|
7712
|
-
const
|
|
7773
|
+
if (groundMarks.length >= maxGroundMarks) evictOldestGroundMark();
|
|
7774
|
+
const geometry = takeSpare((steps + 1) * (steps + 1)) ?? new THREE.PlaneGeometry(2, 2, steps, steps).rotateX(-Math.PI / 2);
|
|
7775
|
+
const grid = geometry.attributes.position;
|
|
7776
|
+
const cell = 2 / steps;
|
|
7713
7777
|
const cos2 = Math.cos(mark.rotation);
|
|
7714
7778
|
const sin2 = Math.sin(mark.rotation);
|
|
7715
|
-
for (let index = 0; index <
|
|
7716
|
-
const localX =
|
|
7717
|
-
const localZ =
|
|
7779
|
+
for (let index = 0; index < grid.count; index++) {
|
|
7780
|
+
const localX = Math.fround(index % (steps + 1) * cell - 1) * radius;
|
|
7781
|
+
const localZ = Math.fround(Math.floor(index / (steps + 1)) * cell - 1) * radius;
|
|
7718
7782
|
const worldX = mark.x + localX * cos2 - localZ * sin2;
|
|
7719
7783
|
const worldZ = mark.z + localX * sin2 + localZ * cos2;
|
|
7720
|
-
|
|
7784
|
+
grid.setXYZ(index, worldX, (options.ground?.heightAt(worldX, worldZ) ?? 0) + mark.lift, worldZ);
|
|
7721
7785
|
}
|
|
7786
|
+
grid.needsUpdate = true;
|
|
7722
7787
|
geometry.computeVertexNormals();
|
|
7788
|
+
geometry.attributes.normal.needsUpdate = true;
|
|
7789
|
+
geometry.boundingSphere = null;
|
|
7790
|
+
geometry.boundingBox = null;
|
|
7723
7791
|
const mesh2 = new THREE.Mesh(geometry, material);
|
|
7724
7792
|
mesh2.receiveShadow = true;
|
|
7725
|
-
|
|
7793
|
+
group.add(mesh2);
|
|
7794
|
+
groundMarks.push({ mesh: mesh2, steps });
|
|
7726
7795
|
}
|
|
7727
7796
|
function addRock(mark) {
|
|
7728
|
-
const mesh2 =
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
mesh2.
|
|
7733
|
-
mesh2.
|
|
7734
|
-
|
|
7797
|
+
const mesh2 = mark.plate ? plateMesh() : rockMesh();
|
|
7798
|
+
const slot = mark.plate ? "plate" : "rock";
|
|
7799
|
+
const index = placed[slot]++ % mesh2.instanceMatrix.count;
|
|
7800
|
+
quaternion.setFromEuler(euler.set(mark.rotation[0], mark.rotation[1], mark.rotation[2]));
|
|
7801
|
+
mesh2.setMatrixAt(index, matrix.compose(position.set(mark.x, mark.y, mark.z), quaternion, scale2.set(mark.scale[0], mark.scale[1], mark.scale[2])));
|
|
7802
|
+
mesh2.setColorAt(index, color.set(mark.color));
|
|
7803
|
+
mesh2.count = Math.min(placed[slot], mesh2.instanceMatrix.count);
|
|
7804
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
7805
|
+
mesh2.instanceColor.needsUpdate = true;
|
|
7806
|
+
}
|
|
7807
|
+
function writeBlood(index, drawn, growth) {
|
|
7808
|
+
quaternion.setFromAxisAngle(up, drawn.rotation);
|
|
7809
|
+
const mesh2 = bloodMesh();
|
|
7810
|
+
mesh2.setMatrixAt(index, matrix.compose(position.set(drawn.position[0], drawn.position[1], drawn.position[2]), quaternion, scale2.set(drawn.scaleX * growth, 1, drawn.scaleZ * growth)));
|
|
7811
|
+
mesh2.instanceMatrix.needsUpdate = true;
|
|
7735
7812
|
}
|
|
7736
7813
|
function addBlood(mark) {
|
|
7737
|
-
const
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
mesh2.scale.multiplyScalar(0.05);
|
|
7743
|
-
blood.push({ mesh: mesh2, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 });
|
|
7744
|
-
return mesh2;
|
|
7814
|
+
const index = placed.blood++ % bloodMesh().instanceMatrix.count;
|
|
7815
|
+
const drawn = { position: [mark.x, mark.y, mark.z], rotation: mark.rotation, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 };
|
|
7816
|
+
blood[index] = drawn;
|
|
7817
|
+
writeBlood(index, drawn, BLOOD_START_GROWTH);
|
|
7818
|
+
bloodMesh().count = Math.min(placed.blood, bloodMesh().instanceMatrix.count);
|
|
7745
7819
|
}
|
|
7746
7820
|
function build(mark) {
|
|
7747
|
-
if (mark.kind === "scorch")
|
|
7748
|
-
if (mark.kind === "dirt")
|
|
7749
|
-
if (mark.kind === "rock")
|
|
7750
|
-
|
|
7751
|
-
}
|
|
7752
|
-
function
|
|
7753
|
-
for (const
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7821
|
+
if (mark.kind === "scorch") conform(mark, scorchMaterials[mark.variant]);
|
|
7822
|
+
else if (mark.kind === "dirt") conform(mark, dirtMaterial);
|
|
7823
|
+
else if (mark.kind === "rock") addRock(mark);
|
|
7824
|
+
else addBlood(mark);
|
|
7825
|
+
}
|
|
7826
|
+
function clearMarks() {
|
|
7827
|
+
for (const drawn of groundMarks) group.remove(drawn.mesh);
|
|
7828
|
+
for (const drawn of groundMarks) drawn.mesh.geometry.dispose();
|
|
7829
|
+
groundMarks.length = 0;
|
|
7830
|
+
for (const geometry of spareGeometries) geometry.dispose();
|
|
7831
|
+
spareGeometries.length = 0;
|
|
7758
7832
|
blood.length = 0;
|
|
7759
|
-
|
|
7833
|
+
placed.blood = placed.rock = placed.plate = 0;
|
|
7834
|
+
for (const mesh2 of [instanced.blood, instanced.rock, instanced.plate]) if (mesh2) mesh2.count = 0;
|
|
7760
7835
|
}
|
|
7761
7836
|
return {
|
|
7762
7837
|
group,
|
|
7763
7838
|
handle(event) {
|
|
7764
|
-
if (event.type === "clear")
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7839
|
+
if (event.type === "clear") clearMarks();
|
|
7840
|
+
else build(event.mark);
|
|
7841
|
+
},
|
|
7842
|
+
prepare() {
|
|
7843
|
+
bloodMesh();
|
|
7844
|
+
rockMesh();
|
|
7845
|
+
plateMesh();
|
|
7770
7846
|
},
|
|
7771
7847
|
update(dt) {
|
|
7772
|
-
for (
|
|
7773
|
-
|
|
7848
|
+
for (let index = 0; index < blood.length; index++) {
|
|
7849
|
+
const drawn = blood[index];
|
|
7850
|
+
if (!drawn || drawn.age > 1) continue;
|
|
7774
7851
|
drawn.age += dt * BLOOD_GROW_RATE;
|
|
7775
|
-
|
|
7776
|
-
drawn.mesh.scale.set(drawn.scaleX * Math.max(0.05, ease3), 1, drawn.scaleZ * Math.max(0.05, ease3));
|
|
7852
|
+
writeBlood(index, drawn, Math.max(BLOOD_START_GROWTH, 1 - Math.pow(1 - Math.min(1, drawn.age), 2.5)));
|
|
7777
7853
|
}
|
|
7778
7854
|
},
|
|
7779
|
-
count: () =>
|
|
7855
|
+
count: () => groundMarks.length + [instanced.blood, instanced.rock, instanced.plate].filter((mesh2) => mesh2 && mesh2.count > 0).length,
|
|
7780
7856
|
dispose() {
|
|
7781
|
-
|
|
7857
|
+
clearMarks();
|
|
7858
|
+
for (const mesh2 of [instanced.blood, instanced.rock, instanced.plate]) mesh2?.dispose();
|
|
7782
7859
|
for (const item of owned) item.dispose();
|
|
7783
7860
|
}
|
|
7784
7861
|
};
|
|
7785
7862
|
}
|
|
7786
7863
|
var SPHERE_DEFAULT_WIDTH = 8;
|
|
7787
7864
|
var SPHERE_DEFAULT_HEIGHT = 6;
|
|
7865
|
+
var MAX_PARKED_MESHES_PER_KIND = 256;
|
|
7788
7866
|
function geometryOf(THREE, particle) {
|
|
7789
7867
|
switch (particle.shape) {
|
|
7790
7868
|
case "cone":
|
|
7791
|
-
return new THREE.ConeGeometry(
|
|
7869
|
+
return new THREE.ConeGeometry(1, 1, particle.segments || void 0, particle.segments2 || 1, false);
|
|
7792
7870
|
case "cone_open":
|
|
7793
|
-
return new THREE.ConeGeometry(
|
|
7871
|
+
return new THREE.ConeGeometry(1, 1, particle.segments || void 0, particle.segments2 || 1, true);
|
|
7794
7872
|
case "sphere":
|
|
7795
|
-
return new THREE.SphereGeometry(
|
|
7873
|
+
return new THREE.SphereGeometry(1, particle.segments || SPHERE_DEFAULT_WIDTH, particle.segments2 || SPHERE_DEFAULT_HEIGHT);
|
|
7796
7874
|
case "icosahedron":
|
|
7797
|
-
return new THREE.IcosahedronGeometry(
|
|
7875
|
+
return new THREE.IcosahedronGeometry(1, particle.segments);
|
|
7798
7876
|
}
|
|
7799
7877
|
}
|
|
7878
|
+
function isCone(particle) {
|
|
7879
|
+
return particle.shape === "cone" || particle.shape === "cone_open";
|
|
7880
|
+
}
|
|
7800
7881
|
function materialOf(THREE, particle) {
|
|
7801
7882
|
if (particle.lit) return new THREE.MeshStandardMaterial({ color: particle.color, roughness: 1, metalness: 0, transparent: true, opacity: particle.opacity, depthWrite: false });
|
|
7802
7883
|
return new THREE.MeshBasicMaterial({ color: particle.color, transparent: true, opacity: particle.opacity, depthWrite: false, ...particle.additive ? { blending: THREE.AdditiveBlending } : {} });
|
|
@@ -7807,51 +7888,82 @@ void main(){
|
|
|
7807
7888
|
(kind) => new THREE.Mesh(geometry, materialOf(THREE, { ...kind, color: 8421504, opacity: 0.5 }))
|
|
7808
7889
|
);
|
|
7809
7890
|
}
|
|
7891
|
+
function geometryKeyOf(particle) {
|
|
7892
|
+
return `${particle.shape}:${particle.segments}:${particle.segments2}`;
|
|
7893
|
+
}
|
|
7810
7894
|
function createMeshLayer(THREE, pool) {
|
|
7811
7895
|
const group = new THREE.Group();
|
|
7812
7896
|
group.name = "workshop-meshes";
|
|
7813
7897
|
const drawn = /* @__PURE__ */ new Map();
|
|
7898
|
+
const geometries = /* @__PURE__ */ new Map();
|
|
7899
|
+
const parked = /* @__PURE__ */ new Map();
|
|
7814
7900
|
const frame = new THREE.Quaternion();
|
|
7815
7901
|
const euler = new THREE.Euler();
|
|
7816
7902
|
const turn = new THREE.Quaternion();
|
|
7817
7903
|
const offset = new THREE.Vector3();
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7904
|
+
let stamp = 0;
|
|
7905
|
+
function geometryFor(particle) {
|
|
7906
|
+
const key = geometryKeyOf(particle);
|
|
7907
|
+
let geometry = geometries.get(key);
|
|
7908
|
+
if (!geometry) {
|
|
7909
|
+
geometry = geometryOf(THREE, particle);
|
|
7910
|
+
geometries.set(key, geometry);
|
|
7911
|
+
}
|
|
7912
|
+
return geometry;
|
|
7913
|
+
}
|
|
7914
|
+
function acquire(particle) {
|
|
7915
|
+
const parkingKey = `${geometryKeyOf(particle)}|${particle.lit}|${particle.additive}`;
|
|
7916
|
+
const mesh2 = parked.get(parkingKey)?.pop() ?? new THREE.Mesh(geometryFor(particle), materialOf(THREE, particle));
|
|
7917
|
+
mesh2.material.color.set(particle.color);
|
|
7918
|
+
mesh2.frustumCulled = false;
|
|
7919
|
+
mesh2.renderOrder = particle.additive ? 5 : 3;
|
|
7920
|
+
group.add(mesh2);
|
|
7921
|
+
return { mesh: mesh2, parkingKey, stamp };
|
|
7922
|
+
}
|
|
7923
|
+
function park(entry) {
|
|
7924
|
+
entry.mesh.removeFromParent();
|
|
7925
|
+
let free = parked.get(entry.parkingKey);
|
|
7926
|
+
if (!free) {
|
|
7927
|
+
free = [];
|
|
7928
|
+
parked.set(entry.parkingKey, free);
|
|
7929
|
+
}
|
|
7930
|
+
if (free.length < MAX_PARKED_MESHES_PER_KIND) free.push(entry.mesh);
|
|
7931
|
+
else entry.mesh.material.dispose();
|
|
7822
7932
|
}
|
|
7823
7933
|
return {
|
|
7824
7934
|
group,
|
|
7825
7935
|
sync() {
|
|
7826
|
-
|
|
7936
|
+
stamp++;
|
|
7827
7937
|
for (const particle of pool.particles) {
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
mesh2.frustumCulled = false;
|
|
7833
|
-
mesh2.renderOrder = particle.additive ? 5 : 3;
|
|
7834
|
-
drawn.set(particle.id, mesh2);
|
|
7835
|
-
group.add(mesh2);
|
|
7938
|
+
let entry = drawn.get(particle.id);
|
|
7939
|
+
if (!entry) {
|
|
7940
|
+
entry = acquire(particle);
|
|
7941
|
+
drawn.set(particle.id, entry);
|
|
7836
7942
|
}
|
|
7943
|
+
entry.stamp = stamp;
|
|
7944
|
+
const mesh2 = entry.mesh;
|
|
7837
7945
|
frame.set(particle.frame[0], particle.frame[1], particle.frame[2], particle.frame[3]);
|
|
7838
7946
|
offset.set(particle.at[0], particle.at[1], particle.at[2]).multiplyScalar(particle.scale).applyQuaternion(frame);
|
|
7839
7947
|
mesh2.position.set(particle.x + offset.x, particle.y + offset.y, particle.z + offset.z);
|
|
7840
7948
|
turn.setFromEuler(euler.set(particle.rx, particle.ry, particle.rz));
|
|
7841
7949
|
mesh2.quaternion.copy(frame).multiply(turn);
|
|
7842
|
-
mesh2.scale.
|
|
7950
|
+
mesh2.scale.set(particle.radius * particle.scale, (isCone(particle) ? particle.height : particle.radius) * particle.scale, particle.radius * particle.scale);
|
|
7843
7951
|
mesh2.material.opacity = particle.opacity;
|
|
7844
7952
|
}
|
|
7845
|
-
for (const [id,
|
|
7846
|
-
if (
|
|
7847
|
-
|
|
7953
|
+
for (const [id, entry] of drawn) {
|
|
7954
|
+
if (entry.stamp === stamp) continue;
|
|
7955
|
+
park(entry);
|
|
7848
7956
|
drawn.delete(id);
|
|
7849
7957
|
}
|
|
7850
7958
|
return pool.count;
|
|
7851
7959
|
},
|
|
7852
7960
|
dispose() {
|
|
7853
|
-
for (const
|
|
7961
|
+
for (const entry of drawn.values()) park(entry);
|
|
7854
7962
|
drawn.clear();
|
|
7963
|
+
for (const free of parked.values()) for (const mesh2 of free) mesh2.material.dispose();
|
|
7964
|
+
parked.clear();
|
|
7965
|
+
for (const geometry of geometries.values()) geometry.dispose();
|
|
7966
|
+
geometries.clear();
|
|
7855
7967
|
group.removeFromParent();
|
|
7856
7968
|
}
|
|
7857
7969
|
};
|
|
@@ -8419,7 +8531,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8419
8531
|
const shocks = createShockLayer(THREE, pools.shocks);
|
|
8420
8532
|
const sprites = createSpriteLayer(THREE, world.sprites(), options.pointScale ?? 700);
|
|
8421
8533
|
const lights = createLightLayer(THREE, pools.lights, options.lightScale ?? Math.PI);
|
|
8422
|
-
const marks = createMarkLayer(THREE, { ground: pools.ground, createCanvas: options.createCanvas, rockGeometry, plateGeometry });
|
|
8534
|
+
const marks = createMarkLayer(THREE, { ground: pools.ground, createCanvas: options.createCanvas, rockGeometry, plateGeometry, ...options.markLimits });
|
|
8423
8535
|
root.add(puffs.mesh, sparks.mesh, glows.mesh, chunks.rocks, chunks.plates, shocks.group, lights.group, sprites.additive, sprites.normal, marks.group);
|
|
8424
8536
|
const stopMarks = world.onMarks((event) => marks.handle(event));
|
|
8425
8537
|
const overlay = options.overlay ? createScreenOverlay(options.overlay) : void 0;
|
|
@@ -8445,6 +8557,16 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8445
8557
|
const position = options.camera.position;
|
|
8446
8558
|
world.setCamera([position.x, position.y, position.z]);
|
|
8447
8559
|
}
|
|
8560
|
+
function attachWorkshopLayers() {
|
|
8561
|
+
const engine = world.peekWorkshop();
|
|
8562
|
+
if (!engine || engine === workshopEngine) return;
|
|
8563
|
+
workshopLayers?.dispose();
|
|
8564
|
+
if (workshopLayers) root.remove(workshopLayers.group);
|
|
8565
|
+
workshopEngine = engine;
|
|
8566
|
+
workshopLayers = createWorkshopLayers(THREE, engine, options.pointScale ?? 700, 1);
|
|
8567
|
+
root.add(workshopLayers.group);
|
|
8568
|
+
applyLayers();
|
|
8569
|
+
}
|
|
8448
8570
|
function syncAll() {
|
|
8449
8571
|
lastDrawn.puffs = puffs.sync();
|
|
8450
8572
|
lastDrawn.sparks = sparks.sync();
|
|
@@ -8453,15 +8575,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8453
8575
|
lastDrawn.shocks = shocks.sync();
|
|
8454
8576
|
lastDrawn.sprites = sprites.sync();
|
|
8455
8577
|
lights.sync();
|
|
8456
|
-
|
|
8457
|
-
if (engine && engine !== workshopEngine) {
|
|
8458
|
-
workshopLayers?.dispose();
|
|
8459
|
-
if (workshopLayers) root.remove(workshopLayers.group);
|
|
8460
|
-
workshopEngine = engine;
|
|
8461
|
-
workshopLayers = createWorkshopLayers(THREE, engine, options.pointScale ?? 700, 1);
|
|
8462
|
-
root.add(workshopLayers.group);
|
|
8463
|
-
applyLayers();
|
|
8464
|
-
}
|
|
8578
|
+
attachWorkshopLayers();
|
|
8465
8579
|
const workshopCalls = workshopLayers?.sync() ?? 0;
|
|
8466
8580
|
const glow = pools.lights.glow;
|
|
8467
8581
|
uniforms.uGlowPos.value.set(glow.x, glow.y, glow.z);
|
|
@@ -8514,6 +8628,9 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
8514
8628
|
},
|
|
8515
8629
|
warmUpProbes() {
|
|
8516
8630
|
releaseAnchors();
|
|
8631
|
+
marks.prepare();
|
|
8632
|
+
world.workshop();
|
|
8633
|
+
attachWorkshopLayers();
|
|
8517
8634
|
const meshes = createMeshLayerProbes(THREE);
|
|
8518
8635
|
for (const mesh2 of meshes) mesh2.frustumCulled = false;
|
|
8519
8636
|
const group = new THREE.Group();
|