📖

日々の記録 2025-03-22

に公開

Three.js で頂点の座標をマウスで変更できるような事をしたい

標準で何かある ?

helper は情報を表示するためのもののよう。

TransformControls が期待したものに近そう。

https://threejs.org/docs/#examples/en/controls/TransformControls

サンプル

https://threejs.org/examples/#misc_controls_transform

サンプルのソース

https://github.com/mrdoob/three.js/blob/master/examples/misc_controls_transform.html

とりあえずやる事

  • 頂点の位置にオブジェクトを作成
  • マウスのクリックを検知する
  • マウスをクリックした時の位置を取得する
  • マウスをクリックした位置から Raycast を飛ばす
  • Raycast と交わるオブジェクトを取得
  • 交わったオブジェクトに TransformControls を attach
  • オブジェクトの位置が変わったら頂点の座標を変更する
  • 三角形の頂点をクリックしたら頂点を選択した状態にする
  • 頂点を選択したら TranformControls を頂点

というか line の頂点の座標ってどうやって変更できるんだ ?

今のソース

    this.line = new THREE.Line(
      new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3( -1, 0, 0 ),
        new THREE.Vector3( 0, 1, 0 ),
        new THREE.Vector3( 1, 0, 0 )
      ]),
      new THREE.LineBasicMaterial( { color: 0x0000ff } )
    );

頂点座標の配列を外に出して、変更してみたけど、それではダメ・
直接 geometry をいじって、needUpdates を true にする

    const positionAttribute = this.line.geometry.attributes.position;
    positionAttribute.setX(0, Math.sin( Date.now() * 0.001 ) * 2);
    positionAttribute.needsUpdate = true;

raycaster の intersectObjects が期待した結果を返さない

サンプルに従って下記のように書いたのだけど、なんか期待した通りにとれていなない

const x = ( event.clientX / window.innerWidth ) * 2 - 1
const y = - ( event.clientY / window.innerHeight ) * 2 + 1

あ、window 使うの微妙なのかも

https://ics.media/tutorial-three/raycast/

  const element = event.currentTarget;
  // canvas要素上のXY座標
  const x = event.clientX - element.offsetLeft;
  const y = event.clientY - element.offsetTop;
  // canvas要素の幅・高さ
  const w = element.offsetWidth;
  const h = element.offsetHeight;

  // -1〜+1の範囲で現在のマウス座標を登録する
  mouse.x = ( x / w ) * 2 - 1;
  mouse.y = -( y / h ) * 2 + 1;

Discussion