feat: branding furni image position + scale (MPU background editor)

Renderer support for the in-client image position editor:
- FurnitureBrandedImageVisualization applies offsetX/Y to the branded image
  layer only (offsetZ stays as z-index/depth), so the image can be moved
  without shifting the furni frame
- new `scale` branding key + FURNITURE_BRANDING_SCALE: zooms the image via a
  real per-sprite scale (RoomObjectSprite.scale, default 1, applied in
  RoomSpriteCanvas) — NOT by writing the read-only width/height
- AssetManager loads external raster images (png/jpg/…) via a CORS <img> +
  Texture.from instead of Assets.load (which didn't load cross-origin images);
  branding image download failures are now surfaced instead of swallowed
This commit is contained in:
medievalshell
2026-05-28 15:29:42 +02:00
parent 238592cd72
commit 9ece87240e
7 changed files with 142 additions and 8 deletions
@@ -702,11 +702,13 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
if(extendedSprite.texture !== objectSprite.texture) extendedSprite.setTexture(objectSprite.texture);
const sx = Math.abs(extendedSprite.scale.x) || 1;
const sy = Math.abs(extendedSprite.scale.y) || 1;
// Per-sprite zoom (objectSprite.scale, default 1) combined with flip.
// Setting the magnitude directly (instead of reading the previous
// scale) avoids compounding across frames.
const magnitude = (objectSprite.scale && (objectSprite.scale > 0)) ? objectSprite.scale : 1;
extendedSprite.scale.x = objectSprite.flipH ? -sx : sx;
extendedSprite.scale.y = objectSprite.flipV ? -sy : sy;
extendedSprite.scale.x = objectSprite.flipH ? -magnitude : magnitude;
extendedSprite.scale.y = objectSprite.flipV ? -magnitude : magnitude;
}
extendedSprite.x = Math.round(sprite.x);