@ninkch/dsh-infinite-canvas 0.19.3 → 0.19.4

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.
@@ -3528,7 +3528,10 @@ export function cameraFlyStep(cam, input, dt, opts) {
3528
3528
  * 单位一律是 CSS 像素 → 同一相机/同一 CSS 尺寸下两者必然一致(历史 bug:绘制用设备像素、拾取用 CSS,命中区偏移)。
3529
3529
  */
3530
3530
  export function gizmoMetrics(cam, sel, hCss, originOverride) {
3531
- const origin = originOverride || v3(sel.pos.x, sel.pos.y + (Number(sel.poseCenterY) || 0), sel.pos.z);
3531
+ // 轴心 = 物体自身坐标系原点(人物是脚底中心),**不随姿态上浮**。
3532
+ // 轴朝向由 objectAxes(sel) 给出 → 物体旋转时轴跟着转(人物倒地后 z 轴仍指向头)。
3533
+ // 需要「轴心跟随身体」的场合显式传 originOverride(见 render 里的 gizmoFollowBody 开关)。
3534
+ const origin = originOverride || v3(sel.pos.x, sel.pos.y, sel.pos.z);
3532
3535
  const depth = depthOf(cam, origin);
3533
3536
  const pxWorld = pixelSizeAt(cam, hCss, depth);
3534
3537
  const minWorld = Math.max(0.25, (Number(sel.h) || 1.7) / 3);
@@ -5551,8 +5554,13 @@ export function createDirectorGlRenderer(canvas) {
5551
5554
  if (o.gizmo && o.selectedId) {
5552
5555
  const sel = (scene.objects || []).find((x) => x.id === o.selectedId);
5553
5556
  if (sel) {
5554
- // gizmo 跟随姿态中心(倒地/下蹲时身体不在原点:让轴心贴住身体,而非留在地面)
5555
- const origin = v3(sel.pos.x, sel.pos.y + (Number(sel.poseCenterY) || 0), sel.pos.z);
5557
+ // 轴心默认在物体原点(人物 = 脚底中心),轴朝向由 objectAxes(sel) 给出
5558
+ // → 物体旋转时轴跟着转(人物倒地后 z 轴仍指向头),不是固定世界坐标。
5559
+ // 「跟随身体」是显式开关:仅当选中项或场景打开 gizmoFollowBody 时才抬到髋高。
5560
+ const followBody = !!(sel.gizmoFollowBody || o.gizmoFollowBody);
5561
+ const origin = followBody
5562
+ ? v3(sel.pos.x, sel.pos.y + (Number(sel.poseCenterY) || 0), sel.pos.z)
5563
+ : v3(sel.pos.x, sel.pos.y, sel.pos.z);
5556
5564
  // 屏幕恒定大小(Blender: wm_gizmo_calculate_scale):轴长 105 CSS px,环 0.62×轴长。
5557
5565
  // 尺寸唯一来源 gizmoMetrics,拾取用同一个函数 → 不可能再出现「画的位置和点不中」。
5558
5566
  const gm = gizmoMetrics(cam, sel, hCss, origin);
@@ -5939,7 +5947,12 @@ export function directorPickGizmo(scene, selectedId, w, h, sx, sy) {
5939
5947
  if (!cam) return null;
5940
5948
  // 与绘制完全同源:精确屏幕投影 + 同一个 gizmoMetrics(w/h 都是 CSS 尺寸)
5941
5949
  const project = (p) => directorScreenOf(cam, w, h, p);
5942
- const gm = gizmoMetrics(cam, sel, h);
5950
+ // 轴心规则必须与绘制一致:默认物体原点,只有显式打开「跟随身体」才抬到髋高
5951
+ const pickFollow = !!(sel.gizmoFollowBody || scene.gizmoFollowBody);
5952
+ const pickOrigin = pickFollow
5953
+ ? v3(sel.pos.x, sel.pos.y + (Number(sel.poseCenterY) || 0), sel.pos.z)
5954
+ : v3(sel.pos.x, sel.pos.y, sel.pos.z);
5955
+ const gm = gizmoMetrics(cam, sel, h, pickOrigin);
5943
5956
  const origin = gm.origin, L = gm.L, R = gm.R;
5944
5957
  const ax = objectAxes(sel);
5945
5958
  const AXES = [['x', ax.x], ['y', ax.y], ['z', ax.z]];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ninkch/dsh-infinite-canvas",
3
- "version": "0.19.3",
3
+ "version": "0.19.4",
4
4
  "description": "Node-based short-drama studio for DeepSeek Harness: script → storyboard → assets → shots → voiced, subtitled final cut on an infinite canvas.",
5
5
  "keywords": [
6
6
  "dsh",