@blorkfield/overlay-core 0.11.0 → 0.11.2

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.js CHANGED
@@ -461,6 +461,17 @@ function createBodyFromVertices(id, x, y, vertices, renderOptions) {
461
461
  render: renderOptions
462
462
  });
463
463
  Matter2.Body.setPosition(body, { x, y });
464
+ if (!body.parts.every((part) => part.vertices && part.vertices.length >= 3)) {
465
+ logger.warn(LOG_PREFIX2, `fromVertices produced degenerate parts, falling back to circle`, { id });
466
+ return Matter2.Bodies.circle(x, y, DEFAULT_RADIUS, {
467
+ restitution: 0.3,
468
+ friction: 0.1,
469
+ frictionAir: 0.01,
470
+ density: 5e-3,
471
+ label: `entity:${id}`,
472
+ render: renderOptions
473
+ });
474
+ }
464
475
  return body;
465
476
  }
466
477
  function createBoundariesWithFloorConfig(bounds, floorConfig) {
@@ -652,11 +663,26 @@ async function createBoxObstacleWithInfo(id, config, isStatic = true) {
652
663
  }
653
664
  }
654
665
  });
655
- const spriteOffsetX = (config.x - body.position.x) / scaledWidth;
656
- const spriteOffsetY = (config.y - body.position.y) / scaledHeight;
657
- if (body.render.sprite) {
658
- body.render.sprite.xOffset = 0.5 + spriteOffsetX;
659
- body.render.sprite.yOffset = 0.5 + spriteOffsetY;
666
+ if (!body.parts.every((part) => part.vertices && part.vertices.length >= 3)) {
667
+ logger.warn(LOG_PREFIX2, `fromVertices produced degenerate obstacle, falling back to rectangle`, { id });
668
+ body = Matter2.Bodies.rectangle(config.x, config.y, scaledWidth, scaledHeight, {
669
+ isStatic,
670
+ label: `obstacle:${id}`,
671
+ render: {
672
+ sprite: {
673
+ texture: config.imageUrl,
674
+ xScale: spriteScale,
675
+ yScale: spriteScale
676
+ }
677
+ }
678
+ });
679
+ } else {
680
+ const spriteOffsetX = (config.x - body.position.x) / scaledWidth;
681
+ const spriteOffsetY = (config.y - body.position.y) / scaledHeight;
682
+ if (body.render.sprite) {
683
+ body.render.sprite.xOffset = 0.5 + spriteOffsetX;
684
+ body.render.sprite.yOffset = 0.5 + spriteOffsetY;
685
+ }
660
686
  }
661
687
  } else {
662
688
  body = Matter2.Bodies.rectangle(config.x, config.y, scaledWidth, scaledHeight, {
@@ -705,6 +731,10 @@ async function createObstacleAsync(id, config, isStatic = true) {
705
731
  }
706
732
  });
707
733
  Matter2.Body.setPosition(body, { x: config.x, y: config.y });
734
+ if (!body.parts.every((part) => part.vertices && part.vertices.length >= 3)) {
735
+ logger.warn(LOG_PREFIX2, `Image obstacle fromVertices degenerate, falling back to rectangle`, { id });
736
+ return createObstacle(id, config, isStatic);
737
+ }
708
738
  return body;
709
739
  }
710
740
  logger.warn(LOG_PREFIX2, `Image obstacle shape extraction failed, falling back to rectangle`, { id });
@@ -3082,11 +3112,12 @@ var OverlayScene = class {
3082
3112
  maxDimension = Math.max(maxDimension, dims.width, dims.height);
3083
3113
  }
3084
3114
  if (maxDimension === 0) maxDimension = 100;
3115
+ const spaceWidth = letterSize / 3;
3085
3116
  const calculateLineWidth = (line) => {
3086
3117
  let width = 0;
3087
3118
  for (const char of line) {
3088
3119
  if (char === " ") {
3089
- width += 20;
3120
+ width += spaceWidth;
3090
3121
  } else if (/^[A-Za-z0-9]$/.test(char)) {
3091
3122
  const dims = charDimensions.get(char);
3092
3123
  if (dims) {
@@ -3144,7 +3175,6 @@ var OverlayScene = class {
3144
3175
  for (let i = 0; i < chars.length; i++) {
3145
3176
  const char = chars[i];
3146
3177
  if (char === " ") {
3147
- const spaceWidth = config.letterSpacing ?? letterSize;
3148
3178
  currentX += spaceWidth;
3149
3179
  globalCharIndex++;
3150
3180
  if (inWord) {
@@ -3421,13 +3451,20 @@ var OverlayScene = class {
3421
3451
  x: currentX + v.x,
3422
3452
  y: currentY + v.y
3423
3453
  }));
3424
- const body = Matter5.Bodies.fromVertices(glyphCenterX, glyphCenterY, [worldVertices], {
3454
+ let body = Matter5.Bodies.fromVertices(glyphCenterX, glyphCenterY, [worldVertices], {
3425
3455
  isStatic,
3426
3456
  label: `obstacle:${id}`,
3427
3457
  render: {
3428
3458
  visible: false
3429
3459
  }
3430
3460
  });
3461
+ if (!body.parts.every((part) => part.vertices && part.vertices.length >= 3)) {
3462
+ body = Matter5.Bodies.rectangle(glyphCenterX, glyphCenterY, Math.max(glyphWidth, 1), Math.max(Math.abs(glyphHeight), 1), {
3463
+ isStatic,
3464
+ label: `obstacle:${id}`,
3465
+ render: { visible: false }
3466
+ });
3467
+ }
3431
3468
  const offsetX = currentX - body.position.x;
3432
3469
  const offsetY = currentY - body.position.y;
3433
3470
  let pressureThreshold;