@adatechnology/game-interactables-three 0.1.14 → 0.2.0
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.d.ts +33 -12
- package/dist/index.global.js +210 -65
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +68 -45
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
// src/effects.ts
|
|
2
|
+
import { warnOnce } from "@adatechnology/game-contracts";
|
|
3
|
+
|
|
4
|
+
// src/routed-particles.ts
|
|
5
|
+
var channel = (value) => Math.round(Math.min(1, Math.max(0, value)) * 255);
|
|
6
|
+
var rgb = (red, green, blue) => channel(red) << 16 | channel(green) << 8 | channel(blue);
|
|
7
|
+
var EFFECT_OF = { smoke: "particle_puff", steam: "particle_puff", fire: "particle_glow", spark: "particle_streak" };
|
|
8
|
+
var isRoutedKind = (kind) => EFFECT_OF[kind] !== void 0;
|
|
9
|
+
function routedParticleRequest(particle) {
|
|
10
|
+
const { kind, flag, tint } = particle;
|
|
11
|
+
const look = lookOf(kind, flag, tint);
|
|
12
|
+
return {
|
|
13
|
+
effect: EFFECT_OF[kind],
|
|
14
|
+
point: particle.position,
|
|
15
|
+
values: {
|
|
16
|
+
vx: particle.velocity[0],
|
|
17
|
+
vy: particle.velocity[1],
|
|
18
|
+
vz: particle.velocity[2],
|
|
19
|
+
life: particle.life,
|
|
20
|
+
size: particle.startSize,
|
|
21
|
+
grow: particle.endSize / particle.startSize,
|
|
22
|
+
color: look.color,
|
|
23
|
+
alpha: look.alpha,
|
|
24
|
+
gravity: 0,
|
|
25
|
+
drag: 0
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function lookOf(kind, flag, tint) {
|
|
30
|
+
if (kind === "smoke") return { color: rgb(tint, tint, tint), alpha: 0.55 };
|
|
31
|
+
if (kind === "steam") return { color: rgb(tint, tint, tint), alpha: 0.4 };
|
|
32
|
+
if (kind === "spark") return { color: rgb(1, 0.75, 0.3), alpha: 1 };
|
|
33
|
+
if (flag) return { color: rgb(0.25 + 0.15 * tint, 0.5 + 0.2 * tint, 1), alpha: 0.95 };
|
|
34
|
+
return { color: rgb(1, Math.max(0.15, 0.85 - tint * 0.1), 0.25), alpha: 0.8 };
|
|
35
|
+
}
|
|
36
|
+
|
|
1
37
|
// src/effects.ts
|
|
2
38
|
var POOLS = ["smoke", "steam", "fire", "water", "spark"];
|
|
3
39
|
var WEIGHT = { smoke: 0.27, steam: 0.15, fire: 0.2, water: 0.28, spark: 0.1 };
|
|
@@ -172,6 +208,12 @@ function createEffects(THREE, a, b = {}) {
|
|
|
172
208
|
let stamp = 0;
|
|
173
209
|
let clock = 0;
|
|
174
210
|
const spawn = (p, x, y, z, vx, vy, vz, life, s0, s1, tint, flag = 0, ground = -1e9) => {
|
|
211
|
+
const sink = isRoutedKind(p.kind) ? options.effects?.() : void 0;
|
|
212
|
+
if (sink) {
|
|
213
|
+
sink.play(routedParticleRequest({ kind: p.kind, flag, position: [x, y, z], velocity: [vx, vy, vz], life, startSize: s0, endSize: s1, tint }));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (isRoutedKind(p.kind)) warnOnce("game-interactables-three.own-particles", "game-interactables-three drew its smoke, steam, fire and sparks with pools of its own because the host lent no effects world (options.effects); pass the host effects so the particles share one budget");
|
|
175
217
|
if (p.count >= p.cap) return;
|
|
176
218
|
const i = p.count++;
|
|
177
219
|
p.pos[i * 3] = x;
|
|
@@ -662,43 +704,12 @@ function createEffects(THREE, a, b = {}) {
|
|
|
662
704
|
};
|
|
663
705
|
}
|
|
664
706
|
|
|
665
|
-
// src/
|
|
666
|
-
|
|
667
|
-
const count = Math.max(2, Math.floor(n));
|
|
668
|
-
const span = Math.hypot(b[0] - a[0], b[2] - a[2]) || Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
669
|
-
const depth = Math.max(0, sag);
|
|
670
|
-
const out = [];
|
|
671
|
-
let shape = () => 0;
|
|
672
|
-
if (depth > 1e-6 && span > 1e-6) {
|
|
673
|
-
let lo = 1e-4;
|
|
674
|
-
let hi = span * 1e3;
|
|
675
|
-
for (let i = 0; i < 80; i++) {
|
|
676
|
-
const c2 = (lo + hi) / 2;
|
|
677
|
-
const d = c2 * (Math.cosh(span / (2 * c2)) - 1);
|
|
678
|
-
if (d > depth) lo = c2;
|
|
679
|
-
else hi = c2;
|
|
680
|
-
}
|
|
681
|
-
const c = (lo + hi) / 2;
|
|
682
|
-
shape = (s) => c * (Math.cosh((s - 0.5) * span / c) - Math.cosh(span / (2 * c)));
|
|
683
|
-
}
|
|
684
|
-
for (let i = 0; i < count; i++) {
|
|
685
|
-
const s = i / (count - 1);
|
|
686
|
-
out.push([a[0] + (b[0] - a[0]) * s, a[1] + (b[1] - a[1]) * s + shape(s), a[2] + (b[2] - a[2]) * s]);
|
|
687
|
-
}
|
|
688
|
-
return out;
|
|
689
|
-
}
|
|
690
|
-
function createCord(THREE, points, radius, material, radialSegments = 5) {
|
|
691
|
-
if (points.length < 2) throw new Error("createCord needs at least two points");
|
|
692
|
-
const curve = new THREE.CatmullRomCurve3(points.map((p) => new THREE.Vector3(p[0], p[1], p[2])), false, "centripetal");
|
|
693
|
-
const segments = Math.max(4, (points.length - 1) * 4);
|
|
694
|
-
const mesh = new THREE.Mesh(new THREE.TubeGeometry(curve, segments, radius, radialSegments, false), material);
|
|
695
|
-
mesh.name = "cord";
|
|
696
|
-
mesh.castShadow = true;
|
|
697
|
-
return mesh;
|
|
698
|
-
}
|
|
707
|
+
// src/adapter.ts
|
|
708
|
+
import { createCord, catenary } from "@adatechnology/game-shapes-three";
|
|
699
709
|
|
|
700
710
|
// src/mesh.ts
|
|
701
711
|
import { markKitOrigin } from "@adatechnology/game-contracts";
|
|
712
|
+
import { LIGHT_PRIORITY } from "@adatechnology/game-render-three";
|
|
702
713
|
import { createShapeRecorder } from "@adatechnology/game-props3d";
|
|
703
714
|
import { colorChannels, generate } from "@adatechnology/game-shapes";
|
|
704
715
|
|
|
@@ -1092,6 +1103,7 @@ function createMeshApi(THREE, options = {}) {
|
|
|
1092
1103
|
if (first !== k) materialAlias[k] = first;
|
|
1093
1104
|
}
|
|
1094
1105
|
const lightsOut = [];
|
|
1106
|
+
const sourcesOut = [];
|
|
1095
1107
|
const build = (batches, points, id, into, materialFor) => {
|
|
1096
1108
|
for (const batch of batches) {
|
|
1097
1109
|
const g = new THREE.BufferGeometry();
|
|
@@ -1113,6 +1125,14 @@ function createMeshApi(THREE, options = {}) {
|
|
|
1113
1125
|
}
|
|
1114
1126
|
for (const point of points) {
|
|
1115
1127
|
const l = point.data;
|
|
1128
|
+
if (options.lights) {
|
|
1129
|
+
const bulb = new THREE.Object3D();
|
|
1130
|
+
bulb.name = "lamp";
|
|
1131
|
+
bulb.position.set(point.position[0], point.position[1], point.position[2]);
|
|
1132
|
+
into.add(bulb);
|
|
1133
|
+
sourcesOut.push(options.lights.addSource({ owner: "interactables.lamp", priority: LIGHT_PRIORITY.lamp, color: l.color, intensity: 1, distance: l.range, position: [0, 0, 0], follow: bulb }));
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
1116
1136
|
const light = new THREE.PointLight(l.color, 1, l.range);
|
|
1117
1137
|
light.position.set(point.position[0], point.position[1], point.position[2]);
|
|
1118
1138
|
into.add(light);
|
|
@@ -1156,7 +1176,7 @@ function createMeshApi(THREE, options = {}) {
|
|
|
1156
1176
|
}
|
|
1157
1177
|
if (spec && (options.mergeParts ?? quality === "game")) mergeParts(THREE, group, parts, spec, { swayAmplitude: options.swayAmplitude });
|
|
1158
1178
|
if (spec) tagDestruction(group, parts, spec);
|
|
1159
|
-
return { group, parts, lights: lightsOut };
|
|
1179
|
+
return { group, parts, lights: lightsOut, sources: sourcesOut };
|
|
1160
1180
|
}
|
|
1161
1181
|
};
|
|
1162
1182
|
}
|
|
@@ -1348,7 +1368,7 @@ function createScreen(THREE, options) {
|
|
|
1348
1368
|
emissiveIntensity: 0
|
|
1349
1369
|
});
|
|
1350
1370
|
let on = false;
|
|
1351
|
-
let
|
|
1371
|
+
let channel2 = 0;
|
|
1352
1372
|
let clock = 0;
|
|
1353
1373
|
let acc = 0;
|
|
1354
1374
|
const fill = (style, x, y, rw, rh) => {
|
|
@@ -1358,7 +1378,7 @@ function createScreen(THREE, options) {
|
|
|
1358
1378
|
};
|
|
1359
1379
|
const drawBars = () => {
|
|
1360
1380
|
const n = BARS.length;
|
|
1361
|
-
for (let i = 0; i < n; i++) fill(BARS[(i +
|
|
1381
|
+
for (let i = 0; i < n; i++) fill(BARS[(i + channel2) % n], Math.floor(i * w / n), 0, Math.ceil(w / n), Math.floor(h * 0.75));
|
|
1362
1382
|
fill("#101010", 0, Math.floor(h * 0.75), w, h - Math.floor(h * 0.75));
|
|
1363
1383
|
const x = clock * 20 % (w + 12) - 12;
|
|
1364
1384
|
fill("#ffffff", x, Math.floor(h * 0.8), 12, Math.floor(h * 0.1));
|
|
@@ -1373,7 +1393,7 @@ function createScreen(THREE, options) {
|
|
|
1373
1393
|
}
|
|
1374
1394
|
};
|
|
1375
1395
|
const drawScene = () => {
|
|
1376
|
-
const hue =
|
|
1396
|
+
const hue = channel2 * 40 % 360;
|
|
1377
1397
|
fill(`hsl(${(200 + hue) % 360},60%,${55 + 10 * Math.sin(clock * 0.3)}%)`, 0, 0, w, Math.floor(h * 0.65));
|
|
1378
1398
|
fill(`hsl(${(110 + hue) % 360},40%,32%)`, 0, Math.floor(h * 0.65), w, h - Math.floor(h * 0.65));
|
|
1379
1399
|
const sx = (0.5 + 0.4 * Math.sin(clock * 0.5)) * w;
|
|
@@ -1385,9 +1405,9 @@ function createScreen(THREE, options) {
|
|
|
1385
1405
|
const draw = () => {
|
|
1386
1406
|
if (!on) {
|
|
1387
1407
|
fill("#000000", 0, 0, w, h);
|
|
1388
|
-
} else if (
|
|
1408
|
+
} else if (channel2 % 3 === 0) {
|
|
1389
1409
|
drawBars();
|
|
1390
|
-
} else if (
|
|
1410
|
+
} else if (channel2 % 3 === 1) {
|
|
1391
1411
|
drawNoise();
|
|
1392
1412
|
} else {
|
|
1393
1413
|
drawScene();
|
|
@@ -1408,7 +1428,7 @@ function createScreen(THREE, options) {
|
|
|
1408
1428
|
return on;
|
|
1409
1429
|
},
|
|
1410
1430
|
get channel() {
|
|
1411
|
-
return
|
|
1431
|
+
return channel2;
|
|
1412
1432
|
},
|
|
1413
1433
|
setOn(value) {
|
|
1414
1434
|
on = !!value;
|
|
@@ -1416,7 +1436,7 @@ function createScreen(THREE, options) {
|
|
|
1416
1436
|
apply();
|
|
1417
1437
|
},
|
|
1418
1438
|
setChannel(n) {
|
|
1419
|
-
|
|
1439
|
+
channel2 = Math.max(0, Math.floor(n));
|
|
1420
1440
|
if (on) draw();
|
|
1421
1441
|
},
|
|
1422
1442
|
update(dt) {
|
|
@@ -1515,7 +1535,7 @@ function attachSway(THREE, mesh, options = {}) {
|
|
|
1515
1535
|
function createThreeAdapter(THREE, options = {}) {
|
|
1516
1536
|
return {
|
|
1517
1537
|
THREE,
|
|
1518
|
-
createMeshApi: (o = {}) => createMeshApi(THREE, { quality: options.quality, materials: options.materials, ...o }),
|
|
1538
|
+
createMeshApi: (o = {}) => createMeshApi(THREE, { quality: options.quality, materials: options.materials, ...options.lights ? { lights: options.lights } : {}, ...o }),
|
|
1519
1539
|
applyPose: (group, motion, t) => applyPose(THREE, group, motion, t),
|
|
1520
1540
|
syncObject: (world, objectId, parts, o) => syncObject(THREE, world, objectId, parts, o),
|
|
1521
1541
|
swayMaterial: (base, o) => swayMaterial(THREE, base, o),
|
|
@@ -1531,12 +1551,15 @@ function createThreeAdapter(THREE, options = {}) {
|
|
|
1531
1551
|
catenary
|
|
1532
1552
|
};
|
|
1533
1553
|
}
|
|
1554
|
+
|
|
1555
|
+
// src/cord.ts
|
|
1556
|
+
import { catenary as catenary2, createCord as createCord2 } from "@adatechnology/game-shapes-three";
|
|
1534
1557
|
export {
|
|
1535
1558
|
MATERIAL_KEYS,
|
|
1536
1559
|
applyPose,
|
|
1537
1560
|
attachSway,
|
|
1538
|
-
catenary,
|
|
1539
|
-
createCord,
|
|
1561
|
+
catenary2 as catenary,
|
|
1562
|
+
createCord2 as createCord,
|
|
1540
1563
|
createDefaultMaterials,
|
|
1541
1564
|
createEffects,
|
|
1542
1565
|
createMeshApi,
|