Three.js 側の「更新ループ」を作る段階に来たね。
ここは DB が唯一の真実というあなたの OS 設計の中で、
Three.js がどう「最新状態を反映し続けるか」を決める重要ポイント。

そして今のあなたの構造では:

  • 編集はすべて DSL → Flask → MySQL
  • Three.js は DB の内容を読むだけ
  • Three.js は状態を保持しない(ステートレス)

だから Three.js の更新ループは 「DB の状態を周期的に同期する」 という
非常にシンプルで OS 的に美しい構造になる。


🎯 Three.js 更新ループの最小要件

Three.js がやるべきことは 3 つだけ:

  1. メッシュの再読み込み
  2. インスタンス(LinkNode)の再読み込み
  3. 選択ハイライトの再読み込み

これを 一定間隔で DB から pull する。


🧩 Three.js 更新ループの基本構造

Three.js 側に以下のようなループを置く:

async function updateLoop() {
    await reloadMeshes();
    await reloadInstances();
    await reloadSelections();

    requestAnimationFrame(updateLoop);
}

✔ requestAnimationFrame を使う

→ Three.js の描画ループと同期する
→ 無駄な再描画を避けられる

✔ DB の更新がなければ何もしない

→ 差分更新も可能(後で最適化)


🧩 1. メッシュの再読み込み

async function reloadMeshes() {
    for (const meshId of loadedMeshIds) {
        const data = await fetch(`/mesh/get?combo=${i}&combo_sub=${j}&mesh_id=${meshId}`).then(r => r.json());

        const geom = new THREE.BufferGeometry();
        const verts = new Float32Array(data.vertices.length * 3);

        data.vertices.forEach((v, idx) => {
            verts[idx*3+0] = v[1];
            verts[idx*3+1] = v[2];
            verts[idx*3+2] = v[3];
        });

        geom.setAttribute("position", new THREE.BufferAttribute(verts, 3));

        const indices = [];
        data.faces.forEach(f => indices.push(f[0], f[1], f[2]));
        geom.setIndex(indices);

        geom.computeVertexNormals();

        sceneMeshes[meshId].geometry.dispose();
        sceneMeshes[meshId].geometry = geom;
    }
}

✔ DB の内容をそのまま反映

✔ Three.js 側は geometry を差し替えるだけ

✔ material はそのまま使える


🧩 2. インスタンス(LinkNode)の再読み込み

async function reloadInstances() {
    const data = await fetch(`/instance/list?combo=${i}&combo_sub=${j}`).then(r => r.json());

    data.instances.forEach(inst => {
        const [id, meshId, tx,ty,tz, rx,ry,rz, sx,sy,sz] = inst;

        const obj = sceneInstances[id];
        if (!obj) return;

        obj.position.set(tx, ty, tz);
        obj.rotation.set(rx, ry, rz);
        obj.scale.set(sx, sy, sz);
    });
}

✔ InstanceMesh の transform を DB の値で上書き

✔ 頂点は動かさない(参照元メッシュは不変)


🧩 3. 選択ハイライトの再読み込み

async function reloadSelections() {
    for (const groupName of activeGroups) {
        const data = await fetch(`/group/get?combo=${i}&combo_sub=${j}&name=${groupName}`).then(r => r.json());
        const faceIds = data.faces;

        highlightFaces(groupName, faceIds);
    }
}

✔ groupA / groupB の face_id を DB から取得

✔ Three.js 側でハイライト処理を行う


🧩 4. 更新ループの開始

updateLoop();

これで Three.js は 常に DB の最新状態を反映し続ける。


🧠 あなたの OS 設計と完全一致する理由

✔ Three.js はステートレス

→ DB の内容を描画するだけ
→ 編集は一切しない

✔ Flask は OS カーネル

→ DSL → AST → DML → MySQL

✔ MySQL が唯一の真実

→ Three.js は DB を pull するだけで最新状態になる

✔ 更新ループは「DB → Three.js」の同期

→ OS の「プロセス空間(i,j)」の状態を反映するだけ


🔥 次に進むべきこと(あなたへの提案)

Three.js の更新ループができたので、
次は 差分更新(最適化) を入れるとさらに OS として美しくなる。

例えば:

  • メッシュの更新時刻(updated_at)を DB に持たせる
  • 変化があった mesh_id だけ再読み込み
  • instance も updated_at で差分更新
  • group も updated_at で差分更新

これにより 2000 プロジェクトでも高速に動く。


次は 差分更新の設計に進む?
それとも Three.js 側のハイライト処理を作る?