@adatechnology/game-items-three 0.3.1 → 0.4.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 +13 -1
- package/dist/index.global.js +790 -99
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +64 -11
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -365,14 +365,19 @@ var destruction_default = {
|
|
|
365
365
|
},
|
|
366
366
|
tessellate: {
|
|
367
367
|
cylinder: {
|
|
368
|
-
heightSegments:
|
|
369
|
-
radialSegments:
|
|
368
|
+
heightSegments: 24,
|
|
369
|
+
radialSegments: 40,
|
|
370
|
+
capRings: 6
|
|
370
371
|
},
|
|
371
372
|
box: {
|
|
372
373
|
widthSegments: 6,
|
|
373
374
|
heightSegments: 1,
|
|
374
375
|
depthSegments: 4
|
|
375
376
|
}
|
|
377
|
+
},
|
|
378
|
+
wall: {
|
|
379
|
+
body: 1e-4,
|
|
380
|
+
ends: 25e-5
|
|
376
381
|
}
|
|
377
382
|
}
|
|
378
383
|
},
|
|
@@ -396,14 +401,19 @@ var destruction_default = {
|
|
|
396
401
|
},
|
|
397
402
|
tessellate: {
|
|
398
403
|
cylinder: {
|
|
399
|
-
heightSegments:
|
|
400
|
-
radialSegments:
|
|
404
|
+
heightSegments: 24,
|
|
405
|
+
radialSegments: 40,
|
|
406
|
+
capRings: 6
|
|
401
407
|
},
|
|
402
408
|
box: {
|
|
403
409
|
widthSegments: 6,
|
|
404
410
|
heightSegments: 1,
|
|
405
411
|
depthSegments: 4
|
|
406
412
|
}
|
|
413
|
+
},
|
|
414
|
+
wall: {
|
|
415
|
+
body: 18e-5,
|
|
416
|
+
ends: 22e-5
|
|
407
417
|
}
|
|
408
418
|
}
|
|
409
419
|
}
|
|
@@ -497,12 +507,53 @@ function volumeOf(mesh) {
|
|
|
497
507
|
if (!box2) return 0;
|
|
498
508
|
return (box2.max.x - box2.min.x) * (box2.max.y - box2.min.y) * (box2.max.z - box2.min.z);
|
|
499
509
|
}
|
|
500
|
-
function
|
|
510
|
+
function ringedCylinder(T, p, radial, maxRows, rings) {
|
|
511
|
+
const half = p.height / 2;
|
|
512
|
+
const column = 2 * Math.PI * Math.max(p.radiusTop, p.radiusBottom, 1e-6) / radial;
|
|
513
|
+
const rows = Math.max(1, Math.min(maxRows, Math.round(p.height / column)));
|
|
514
|
+
const points = [];
|
|
515
|
+
if (!p.openEnded) for (let i = 0; i <= rings; i++) points.push(new T.Vector2(p.radiusBottom * i / rings, -half));
|
|
516
|
+
for (let j = 0; j <= rows; j++) points.push(new T.Vector2(p.radiusBottom + (p.radiusTop - p.radiusBottom) * j / rows, -half + p.height * j / rows));
|
|
517
|
+
if (!p.openEnded) for (let i = rings; i >= 0; i--) points.push(new T.Vector2(p.radiusTop * i / rings, half));
|
|
518
|
+
return lathed(T, points, radial, p.thetaStart, p.thetaLength);
|
|
519
|
+
}
|
|
520
|
+
function lathed(T, points, radial, phiStart, phiLength) {
|
|
521
|
+
const geometry = new T.LatheGeometry([...points], radial, phiStart, phiLength);
|
|
522
|
+
geometry.computeVertexNormals();
|
|
523
|
+
const position = geometry.getAttribute("position");
|
|
524
|
+
const normal = geometry.getAttribute("normal");
|
|
525
|
+
const middle = (Math.min(...points.map((point) => point.y)) + Math.max(...points.map((point) => point.y))) / 2;
|
|
526
|
+
for (let i = 0; i < normal.count; i++) {
|
|
527
|
+
if (Math.hypot(normal.getX(i), normal.getY(i), normal.getZ(i)) > 0.5) continue;
|
|
528
|
+
normal.setXYZ(i, 0, position.getY(i) >= middle ? 1 : -1, 0);
|
|
529
|
+
}
|
|
530
|
+
return geometry;
|
|
531
|
+
}
|
|
532
|
+
function finerProfile(T, points, step) {
|
|
533
|
+
const out = [];
|
|
534
|
+
points.forEach((point, index) => {
|
|
535
|
+
const next = points[index + 1];
|
|
536
|
+
out.push(point.clone());
|
|
537
|
+
if (!next) return;
|
|
538
|
+
const pieces = Math.max(1, Math.round(point.distanceTo(next) / step));
|
|
539
|
+
for (let k = 1; k < pieces; k++) out.push(point.clone().lerp(next, k / pieces));
|
|
540
|
+
});
|
|
541
|
+
return out;
|
|
542
|
+
}
|
|
543
|
+
function tessellated(geometry, rule, T) {
|
|
501
544
|
const Shape = geometry.constructor;
|
|
502
545
|
if (geometry.type === "CylinderGeometry" && rule.cylinder) {
|
|
503
|
-
const
|
|
546
|
+
const parameters = geometry.parameters;
|
|
547
|
+
const { radiusTop, radiusBottom, height, openEnded, thetaStart, thetaLength } = parameters;
|
|
548
|
+
if (T && rule.cylinder.capRings !== void 0) return ringedCylinder(T, parameters, rule.cylinder.radialSegments, rule.cylinder.heightSegments, rule.cylinder.capRings);
|
|
504
549
|
return new Shape(radiusTop, radiusBottom, height, rule.cylinder.radialSegments, rule.cylinder.heightSegments, openEnded, thetaStart, thetaLength);
|
|
505
550
|
}
|
|
551
|
+
if (geometry.type === "LatheGeometry" && rule.cylinder && T && rule.cylinder.capRings !== void 0) {
|
|
552
|
+
const { points, segments, phiStart, phiLength } = geometry.parameters;
|
|
553
|
+
if (segments >= rule.cylinder.radialSegments) return void 0;
|
|
554
|
+
const widest = Math.max(...points.map((point) => point.x), 1e-6);
|
|
555
|
+
return lathed(T, finerProfile(T, points, 2 * Math.PI * widest / rule.cylinder.radialSegments), rule.cylinder.radialSegments, phiStart, phiLength);
|
|
556
|
+
}
|
|
506
557
|
if (geometry.type === "BoxGeometry" && rule.box) {
|
|
507
558
|
const { width, height, depth } = geometry.parameters;
|
|
508
559
|
return new Shape(width, height, depth, rule.box.widthSegments, rule.box.heightSegments, rule.box.depthSegments);
|
|
@@ -510,14 +561,14 @@ function tessellated(geometry, rule) {
|
|
|
510
561
|
return void 0;
|
|
511
562
|
}
|
|
512
563
|
var triangleCount = (geometry) => (geometry.index ? geometry.index.count : geometry.getAttribute("position").count) / 3;
|
|
513
|
-
function tessellateShapes(root, rule) {
|
|
564
|
+
function tessellateShapes(root, rule, T) {
|
|
514
565
|
const rebuilt = /* @__PURE__ */ new Map();
|
|
515
566
|
root.traverse((object) => {
|
|
516
567
|
const mesh = object;
|
|
517
568
|
if (!mesh.isMesh) return;
|
|
518
569
|
let fresh = rebuilt.get(mesh.geometry);
|
|
519
570
|
if (!fresh) {
|
|
520
|
-
fresh = tessellated(mesh.geometry, rule);
|
|
571
|
+
fresh = tessellated(mesh.geometry, rule, T);
|
|
521
572
|
if (!fresh) return;
|
|
522
573
|
rebuilt.set(mesh.geometry, fresh);
|
|
523
574
|
}
|
|
@@ -531,10 +582,10 @@ function tessellateShapes(root, rule) {
|
|
|
531
582
|
root.userData.tessellationTriangles = added;
|
|
532
583
|
}
|
|
533
584
|
function tagForDestruction(root, options = {}) {
|
|
534
|
-
const { modelId, weight, size } = options;
|
|
585
|
+
const { modelId, weight, size, three } = options;
|
|
535
586
|
if (weight !== void 0 && weight > 0) root.userData.destructionMass = weight;
|
|
536
587
|
const rule = modelId === void 0 ? void 0 : itemDestruction(modelId);
|
|
537
|
-
if (rule?.tessellate) tessellateShapes(root, rule.tessellate);
|
|
588
|
+
if (rule?.tessellate) tessellateShapes(root, rule.tessellate, three);
|
|
538
589
|
const solid = [];
|
|
539
590
|
root.traverse((object) => {
|
|
540
591
|
const mesh = object;
|
|
@@ -554,6 +605,7 @@ function tagForDestruction(root, options = {}) {
|
|
|
554
605
|
const anchor = solid.reduce((largest, mesh) => volumeOf(mesh) > volumeOf(largest) ? mesh : largest);
|
|
555
606
|
solid.forEach((mesh, index) => {
|
|
556
607
|
mesh.userData.destructionPart = mesh === anchor ? { id: SHELL_PART_ID } : { id: `shell_${index}`, parent: SHELL_PART_ID, kind: "weld" };
|
|
608
|
+
if (rule.wall) mesh.userData.destructionThickness = mesh === anchor ? rule.wall.body : rule.wall.ends;
|
|
557
609
|
});
|
|
558
610
|
const contents = size === void 0 ? void 0 : itemContents({ ...modelId === void 0 ? {} : { model: modelId }, size, ...weight === void 0 ? {} : { weight } });
|
|
559
611
|
if (contents) anchor.userData.destructionContains = { fluid: contents.liquid, liters: contents.liters };
|
|
@@ -6674,7 +6726,7 @@ function buildItem(T, item, options = {}) {
|
|
|
6674
6726
|
const materials = kit.materials.slice(first);
|
|
6675
6727
|
if (options.wear) setWear(materials, options.wear);
|
|
6676
6728
|
root.userData.wear = options.wear ?? 0;
|
|
6677
|
-
if (options.destructible) tagForDestruction(root, { ...kind === "model" && item.model !== void 0 ? { modelId: item.model } : {}, ...item.weight === void 0 ? {} : { weight: item.weight }, size: item.size });
|
|
6729
|
+
if (options.destructible) tagForDestruction(root, { ...kind === "model" && item.model !== void 0 ? { modelId: item.model } : {}, ...item.weight === void 0 ? {} : { weight: item.weight }, size: item.size, three: T });
|
|
6678
6730
|
markKitOrigin(root, { owner: "game-items-three", kind: "item", id: item.id, ...kind === "shape" ? { standIn: true } : {} });
|
|
6679
6731
|
return { root, kind, ...shape ? { shape } : {}, size: item.size, materials };
|
|
6680
6732
|
}
|
|
@@ -7417,6 +7469,7 @@ function createItemsTestModule(options) {
|
|
|
7417
7469
|
const module = {
|
|
7418
7470
|
id: "items_area",
|
|
7419
7471
|
name: text.name,
|
|
7472
|
+
ground: { surface: "tile_floor" },
|
|
7420
7473
|
group: text.group,
|
|
7421
7474
|
state,
|
|
7422
7475
|
placed: () => entries2.map((entry) => ({ id: entry.id, itemId: entry.itemId, group: entry.group, kind: entry.kind, size: entry.size, root: entry.root })),
|