@broberg/bodymap 0.2.8 → 0.3.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/three.cjs CHANGED
@@ -236,6 +236,17 @@ var ANCHORS = {
236
236
  foot_left: [-0.1, 0.02, 0.11],
237
237
  foot_right: [0.1, 0.02, 0.11]
238
238
  };
239
+ var SEAM = 0.18;
240
+ function seamBlend(nearestSq, secondSq) {
241
+ const d1 = Math.sqrt(nearestSq), d2 = Math.sqrt(secondSq);
242
+ const sum = d1 + d2;
243
+ if (!(sum > 0)) return 0;
244
+ const ratio = d1 / sum;
245
+ const t = (ratio - (0.5 - SEAM)) / SEAM;
246
+ if (t <= 0) return 0;
247
+ if (t >= 1) return 0.5;
248
+ return t * t * (3 - 2 * t) * 0.5;
249
+ }
239
250
  var ANCHOR_KEYS = Object.keys(ANCHORS);
240
251
  for (const k of ANCHOR_KEYS) ANCHORS[k][0] = -ANCHORS[k][0];
241
252
  function mergeLabels(locale, overrides) {
@@ -378,6 +389,8 @@ function BodyMap3D(props) {
378
389
  let modelRoot = null;
379
390
  let bodyMesh = null;
380
391
  let vertexRegion = [];
392
+ let vertexNeighbour = [];
393
+ let vertexBlend = new Float32Array(0);
381
394
  let colorAttr = null;
382
395
  let hovered = null;
383
396
  const loader = new GLTFLoader_js.GLTFLoader();
@@ -389,14 +402,32 @@ function BodyMap3D(props) {
389
402
  if (selectedRef.current === key) return paletteRef.current.selected;
390
403
  return baseColorFor(key, paletteRef.current);
391
404
  };
392
- const colorRegion = (key, hex) => {
405
+ const tmp2 = new THREE__namespace.Color();
406
+ const colourOf = (key) => hovered === key ? paletteRef.current.hover : restingHex(key);
407
+ const paint = () => {
393
408
  if (!colorAttr) return;
394
- tmp.set(hex);
395
- for (let i = 0; i < vertexRegion.length; i++) if (vertexRegion[i] === key) colorAttr.setXYZ(i, tmp.r, tmp.g, tmp.b);
409
+ const cache = /* @__PURE__ */ new Map();
410
+ const col = (k) => {
411
+ let c = cache.get(k);
412
+ if (!c) {
413
+ c = new THREE__namespace.Color(colourOf(k));
414
+ cache.set(k, c);
415
+ }
416
+ return c;
417
+ };
418
+ for (let i = 0; i < vertexRegion.length; i++) {
419
+ tmp.copy(col(vertexRegion[i]));
420
+ const w = vertexBlend[i];
421
+ if (w > 0) {
422
+ tmp2.copy(col(vertexNeighbour[i]));
423
+ tmp.lerp(tmp2, w);
424
+ }
425
+ colorAttr.setXYZ(i, tmp.r, tmp.g, tmp.b);
426
+ }
396
427
  colorAttr.needsUpdate = true;
397
428
  };
398
429
  const refresh = () => {
399
- for (const k of ANCHOR_KEYS) colorRegion(k, hovered === k ? paletteRef.current.hover : restingHex(k));
430
+ paint();
400
431
  renderFrame();
401
432
  };
402
433
  const loadModel = (which) => {
@@ -425,18 +456,27 @@ function BodyMap3D(props) {
425
456
  const n = pos.count;
426
457
  const cols = new Float32Array(n * 3);
427
458
  vertexRegion = new Array(n);
459
+ vertexNeighbour = new Array(n);
460
+ vertexBlend = new Float32Array(n);
428
461
  const v = new THREE__namespace.Vector3();
429
462
  for (let i = 0; i < n; i++) {
430
463
  v.fromBufferAttribute(pos, i).applyMatrix4(bodyMesh.matrixWorld);
431
- let best = 0, bd = Infinity;
464
+ let best = 0, second = 0, bd = Infinity, sd = Infinity;
432
465
  for (let a = 0; a < anchorVecs.length; a++) {
433
466
  const d = v.distanceToSquared(anchorVecs[a]);
434
467
  if (d < bd) {
468
+ sd = bd;
469
+ second = best;
435
470
  bd = d;
436
471
  best = a;
472
+ } else if (d < sd) {
473
+ sd = d;
474
+ second = a;
437
475
  }
438
476
  }
439
477
  vertexRegion[i] = ANCHOR_KEYS[best];
478
+ vertexNeighbour[i] = ANCHOR_KEYS[second];
479
+ vertexBlend[i] = seamBlend(bd, sd);
440
480
  }
441
481
  colorAttr = new THREE__namespace.BufferAttribute(cols, 3);
442
482
  geo.setAttribute("color", colorAttr);
@@ -496,10 +536,8 @@ function BodyMap3D(props) {
496
536
  if ((e.buttons || 0) !== 0) return;
497
537
  const k = pick(e.clientX, e.clientY);
498
538
  if (k === hovered) return;
499
- const prev = hovered;
500
539
  hovered = k;
501
- if (prev) colorRegion(prev, restingHex(prev));
502
- if (k) colorRegion(k, paletteRef.current.hover);
540
+ paint();
503
541
  canvas.style.cursor = k ? "pointer" : "default";
504
542
  renderFrame();
505
543
  };
@@ -609,6 +647,7 @@ function BodyMap3D(props) {
609
647
  }
610
648
 
611
649
  exports.BodyMap3D = BodyMap3D;
650
+ exports.seamBlend = seamBlend;
612
651
  exports.serializeReport = serializeReport;
613
652
  //# sourceMappingURL=three.cjs.map
614
653
  //# sourceMappingURL=three.cjs.map