diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/bluebey-studio/guide.html | 4 | ||||
| -rw-r--r-- | public/bluebey-studio/index.html | 1 | ||||
| -rw-r--r-- | public/bluebey-studio/src/main.js | 38 | ||||
| -rw-r--r-- | public/bluebey/guide.pdf | bin | 3568312 -> 3570039 bytes |
4 files changed, 28 insertions, 15 deletions
diff --git a/public/bluebey-studio/guide.html b/public/bluebey-studio/guide.html index b4541a3..0853891 100644 --- a/public/bluebey-studio/guide.html +++ b/public/bluebey-studio/guide.html @@ -107,7 +107,9 @@ </ol> <h3>パソコンでの操作</h3> <ul> - <li>ぶるべーをつかんでドラッグすると、姿を変えずに移動できます。向きはマウスで調整します。</li> + <li>ぶるべーをつかんでドラッグすると、姿を変えずに移動できます(カメラの基準点は動きません)。</li> + <li>Shift を押しながらドラッグすると、カメラ(見ている基準点)を動かせます。</li> + <li>向きは、全身とボーンのスライダーや回転ギズモで調整できます。</li> <li>モデルをクリックすると、その場所に近いボーンが選ばれます。</li> <li>「元に戻す/やり直す(パネル上部の矢印アイコン)」「すべてをランダムに(?!アイコン)」は、どのタブでも使えます。</li> </ul> diff --git a/public/bluebey-studio/index.html b/public/bluebey-studio/index.html index 21a07d4..f076efd 100644 --- a/public/bluebey-studio/index.html +++ b/public/bluebey-studio/index.html @@ -136,6 +136,7 @@ if (window.matchMedia('(max-width: 768px), (max-height: 500px) and (pointer: coa <h3>ポーズ</h3> <ul> <li>右パネルの「ポーズ」でボーンを選び、X/Y/Zのスライダーを動かします。「ポーズ例」から始めると早いです。</li> + <li>ぶるべーをつかんでドラッグすると移動できます。Shiftを押しながらドラッグすると、カメラ(見ている基準点)を動かせます。</li> <li>モデルをクリックすると、その場所にいちばん近いボーンが選ばれます。</li> <li>ギズモ(回転の輪)を直接ドラッグしても回せます。</li> <li>スライダーの値は「休めの姿勢(レストポーズ)」からの差分です。<code>0,0,0</code> で元の姿勢。</li> diff --git a/public/bluebey-studio/src/main.js b/public/bluebey-studio/src/main.js index e6bc785..ac8c04b 100644 --- a/public/bluebey-studio/src/main.js +++ b/public/bluebey-studio/src/main.js @@ -2321,9 +2321,10 @@ async function init() { // --- the mouse on the character ---------------------------------------- // Dragging the model slides it across the view; holding Shift and dragging - // turns it around. Bone posing lives in the panel, so the mouse never grabs a - // bone (see `Rig` in src/rig.js). On a small screen the panel is a sheet over - // the view, so a tap on the view first just dismisses the sheet. + // moves the camera's reference point instead (the phone's two-finger drag). + // Bone posing lives in the panel, so the mouse never grabs a bone (see `Rig` + // in src/rig.js). On a small screen the panel is a sheet over the view, so a + // tap on the view first just dismisses the sheet. const dragRay = new THREE.Raycaster(); const dragNdc = new THREE.Vector2(); const dragHitAt = (event) => { @@ -2355,14 +2356,12 @@ async function init() { } if (!dragHitAt(event)) return; const root = state.pose.root ?? [0, 0, 0]; - const master = state.pose.bones?.master ?? [0, 0, 0]; modelDrag = { pointerId: event.pointerId, - spin: event.shiftKey, + pan: event.shiftKey, x: event.clientX, y: event.clientY, root: [...root], - masterY: master[1] ?? 0, }; view.controls.enabled = false; stage.style.cursor = 'grabbing'; @@ -2373,30 +2372,41 @@ async function init() { if (!modelDrag || event.pointerId !== modelDrag.pointerId) return; const dx = event.clientX - modelDrag.x; const dy = event.clientY - modelDrag.y; - if (modelDrag.spin) { - const bones = { ...(state.pose.bones ?? {}) }; - const master = bones.master ?? [0, 0, 0]; - bones.master = [master[0], round2(modelDrag.masterY + dx * 0.7), master[2]]; - state.pose.bones = bones; + const k = dragScale(); + if (modelDrag.pan) { + // Shift+drag: move the camera's reference point (the same effect as the + // two-finger drag on a phone). The character stays where it is. + const right = new THREE.Vector3(1, 0, 0).applyQuaternion(view.camera.quaternion); + const up = new THREE.Vector3(0, 1, 0).applyQuaternion(view.camera.quaternion); + const move = new THREE.Vector3() + .addScaledVector(right, -dx * k) + .addScaledVector(up, dy * k); + view.target.add(move); + for (const controls of Object.values(view.controlsMap ?? {})) controls.target.add(move); + for (const cam of Object.values(view.cameras ?? {})) cam.position.add(move); + view.captureInto(state.view); } else { - const k = dragScale(); + // Plain drag: slide the character, leaving the camera's reference point + // alone (the one-finger drag on a phone). state.pose.root = [ round2(modelDrag.root[0] + dx * k), round2(modelDrag.root[1] - dy * k), modelDrag.root[2], ]; + app.panel?.onRigChanged?.(); } - app.panel?.onRigChanged?.(); app.needsRender = true; }); const endModelDrag = (event) => { if (!modelDrag || (event && event.pointerId !== modelDrag.pointerId)) return; + const wasPan = modelDrag.pan === true; modelDrag = null; view.controls.enabled = true; stage.style.cursor = ''; if (event) { try { canvas.releasePointerCapture(event.pointerId); } catch { /* ignore */ } } - capturePose(); + if (wasPan) app.actions.syncPanel?.(); + else capturePose(); app.panel?.onRigChanged?.(); app.needsRender = true; }; diff --git a/public/bluebey/guide.pdf b/public/bluebey/guide.pdf Binary files differindex 408cc54..23ccfc0 100644 --- a/public/bluebey/guide.pdf +++ b/public/bluebey/guide.pdf |
