aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/bluebey-studio
diff options
context:
space:
mode:
Diffstat (limited to 'public/bluebey-studio')
-rw-r--r--public/bluebey-studio/guide.html4
-rw-r--r--public/bluebey-studio/index.html1
-rw-r--r--public/bluebey-studio/src/main.js38
3 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;
};