2026年4月19日日曜日

Three.jsのFlyControlsデモ blenderのフライモードに似たナビゲーション

 このカビ菌みたいなのはorbitと違う動きをするので、オリジナルコードかと思ったらjmsの中に入っていた。fly controlerというらしい。

解説もある。

FlyControlsは、BlenderのようなDCCツールのフライモードに似たナビゲーションを可能にします。3D空間のカメラを制限なく任意に変形させることができます(特定のターゲットにフォーカスするなど)。

似てるか、これ

キー操作で飛び回れるというのがポイントのようで、実際飛べました。便利だなこれ。で、ソースを見ながらカメラの勉強をすることにした。


	this.keydown = function ( event ) {
		if ( event.altKey ) {
			return;
		}
		//event.preventDefault();
		switch ( event.keyCode ) {
			case 16: /* shift */ this.movementSpeedMultiplier = .1; break;
			case 87: /*W*/ this.moveState.forward = 1; break;
			case 83: /*S*/ this.moveState.back = 1; break;
			case 65: /*A*/ this.moveState.left = 1; break;
			case 68: /*D*/ this.moveState.right = 1; break;
			case 82: /*R*/ this.moveState.up = 1; break;
			case 70: /*F*/ this.moveState.down = 1; break;
			case 38: /*up*/ this.moveState.pitchUp = 1; break;
			case 40: /*down*/ this.moveState.pitchDown = 1; break;
			case 37: /*left*/ this.moveState.yawLeft = 1; break;
			case 39: /*right*/ this.moveState.yawRight = 1; break;
			case 81: /*Q*/ this.moveState.rollLeft = 1; break;
			case 69: /*E*/ this.moveState.rollRight = 1; break;
		}
		this.updateMovementVector();
		this.updateRotationVector();
	};

さっき自分で動かしてみたキー処理の部分で、動きのフラグをたてて移動と回転の更新をするようだ。この先に欲しいコードがあると思われる。

	this.updateMovementVector = function () {
		var forward = ( this.moveState.forward || ( this.autoForward && ! this.moveState.back ) ) ? 1 : 0;
		this.moveVector.x = ( - this.moveState.left + this.moveState.right );
		this.moveVector.y = ( - this.moveState.down + this.moveState.up );
		this.moveVector.z = ( - forward + this.moveState.back );
		//console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
	};
	this.updateRotationVector = function () {
		this.rotationVector.x = ( - this.moveState.pitchDown + this.moveState.pitchUp );
		this.rotationVector.y = ( - this.moveState.yawRight + this.moveState.yawLeft );
		this.rotationVector.z = ( - this.moveState.rollRight + this.moveState.rollLeft );
		//console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );


controls = new FlyControls( camera, renderer.domElement );

こちらは、呼び出し側の処理で、コンストラクタの第一引数はやはりカメラなので、moveVectorやrotationVectorもカメラに属しているオブジェクトになるはずだ。

と思ったのだがうそで、これは単なるfly中で定義している三次元ベクターだった。

	this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
	this.moveVector = new Vector3( 0, 0, 0 );
	this.rotationVector = new Vector3( 0, 0, 0 );

なるほど、なるほど。あぶねー、

	this.update = function( delta ) {
		if ( this.enabled ) {
			var moveMult = delta * this.movementSpeed;
			var rotMult = delta * this.rollSpeed;
			this.object.translateX( this.moveVector.x * moveMult );
			this.object.translateY( this.moveVector.y * moveMult );
			this.object.translateZ( this.moveVector.z * moveMult );
			if (this.object.position.x < this.clamp.xmin) this.object.position.x = this.clamp.xmin;
			if (this.object.position.x > this.clamp.xmax) this.object.position.x = this.clamp.xmax;
			if (this.object.position.z < this.clamp.zmin) this.object.position.z = this.clamp.zmin;
			if (this.object.position.z > this.clamp.zmax) this.object.position.z = this.clamp.zmax;
			this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize();
			this.object.quaternion.multiply( this.tmpQuaternion );
			// expose the rotation vector for convenience
			this.object.rotation.setFromQuaternion( this.object.quaternion, this.object.rotation.order );
		}
	};

実際はupdateという関数を呼び出しているようだった。objectはobject3Dの事だとすると合点がゆく

なんとなく上のコードで動きそうだが、クオータニオンというのが良く分からなかった。

Threeでの解説は淡白で、すぐwikipediaの解説に飛ぶ。

versors とも呼ばれる単位クォータニオンは、3 次元の物体の空間の向きや回転を表現するのに便利な数学的表記法です。オイラー角に比べて構成が簡単で、ジンバルロックの問題を回避することができます。

つーことは、クオータニオンでどっかで計算して、回転などしかけているということになりそうだ。サンプルを見れば使い方が分かるかもしれない。

const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 );
const vector = new THREE.Vector3( 1, 0, 0 );
vector.applyQuaternion( quaternion );

なんか計算が楽になるしくみっぽい。

			scope.tmpQuaternion.set( scope.rotationVector.x * rotMult, scope.rotationVector.y * rotMult, scope.rotationVector.z * rotMult, 1 ).normalize();
			scope.object.quaternion.multiply( scope.tmpQuaternion );

flyの例ではsetとmultiplyを使っているようだ。scope=cameraと考えてよい模様。




MSX1風フィルタ研究概要

 # MSX1風フィルタ研究概要


近年、MSX1(TMS9918搭載)の独特な16色パレットや水平方向8ドット2色の制限、ドット絵の階調などをエミュレートする**JavaScript/WebGLフィルタ**はほとんど見当たりません。見つかった主な手法は、ドット単位で色を量子化・ディザリングする画像変換ツールやShaderToyなどのシェーダ実験で、MSX1専用ライブラリはごく僅かです。例えば開発者Harayoki氏が公開した**「MSX1エフェクト(MMSXX_MSX1PaletteQuantizer)」**は、AfterEffects/CLI向けにMSX1表示を再現するC++実装(MITライセンス)で、15色パレットを用い8x1ドット内2色制限を満たす手法を採用しています【8†L37-L44】【31†L41-L42】。一方、JavaScript実装としてはPhaserの組み込みパレット(MSX風16色、MIT)【38†L348-L357】や、Construct 3用のGLSLフィルタ(PX_MSX)【78†L398-L402】が存在します。また、汎用のカラー量子化ライブラリ(例:RgbQuant.js【84†L262-L270】)やWebGL効果ライブラリ(glfx.js【92†L278-L280】)をMSXパレット指定で使う方法も考えられます。以下に主要な候補をまとめ、特性・ライセンス・実装例を分析します。


## 候補一覧


- **Harayoki MSX1PaletteQuantizer(C++ AEプラグイン&CLI)** – MITライセンス【31†L24-L26】。AfterEffects向けエフェクトとWindowsコマンドライン版が同梱され、MSX1の画像特性(15色パレット、2色/8ドット、階調型ディザなど)を再現します。内部でまず92色(きれいなディザ用)に量子化→横8ドットごとに2色選択する処理を行う【31†L41-L42】。設定次第で自動ディザやコントラスト調整も可能です。  


  【68†embed_image】*Harayoki氏作成MSX1変換フィルタの出力例【8†L37-L44】(オリジナル:PC-88「グラムキャッツ」タイトル画面)*


  *評価:* パレット精度・ディザ再現性が高く、MSX1制約も踏襲する一方、C++版でWeb実装はないため導入にはWindows環境が必要。コマンド例などはNote記事を参照【28†】。  


- **Phaser.Create.Palettes.MSX(JavaScript)** – Phaserゲームエンジン標準搭載の16色パレット定義(MIT)【38†L348-L357】。MSX風に調整された色配列を返します。  


  ```js

  const MSX_PALETTE = {

    0: '#000', 1: '#191028', 2: '#46af45', 3: '#a1d685',

    4: '#453e78', 5: '#7664fe', 6: '#833129', 7: '#9ec2e8',

    8: '#dc534b', 9: '#e18d79', A: '#d6b97b', B: '#e9d8a1',

    C: '#216c4b', D: '#d365c8', E: '#afaab9', F: '#fff'

  };

  ```  

  *(Phaser公式ソースより【38†L348-L356】)*  


  *評価:* MSX1パレットに近い16色を提供【38†L348-L357】しますが、単なるカラーデータなのでディザやスキャンラインなどは含まず、エンジン内での適用(パレットマッピング等)は別途実装が必要です。  


- **Construct 3 Low Computer: PX_MSXフィルタ(GLSL)** – Construct 3向け商用アセット(PX_MSX_6bit_RGB)で、WebGLポストプロセスエフェクトを提供。MSX色パレットで画面を量子化し、8ビット風演出を行います【78†L398-L402】。  


  *評価:* 実行は容易(Constructにプラグインとして組込むだけ)ですが、商用でソース非公開。MSXパレット適用のみでディザ処理や8x1制約の表現は不明。ライセンスもクローズドで高価。  


- **RgbQuant.js(JavaScript)** – 任意の色数に量子化できるJSライブラリ(MIT)【84†L262-L270】。色数やパレットを指定可能で、ディザリング(誤差拡散)機能もサポート。MSXの15/16色パレットを`initColors`や`palette`オプションで指定すれば、MSX風変換に利用できます。  


  *評価:* 汎用度高くMSXパレット指定可能ですが、レトロVDPの行単位制限などは自動考慮しないため、必要なら自作で制約処理を追加する必要があります。  



- **glfx.js(JavaScript/WebGL)** – WebGL用の画像エフェクトライブラリ(MIT)【92†L278-L280】。ブラーや色調調整フィルタを備え、独自シェーダーの作成も可能。直接「MSXフィルタ」はないものの、Hue/SaturationやPosterize系の組合せで雰囲気を近づける手段として利用できます。  


  *評価:* 既成のMSX専用機能はなし。任意のGLSLフィルタを自作可能で、msxパレットマップやディザシェーダも実装できますが、一から開発が必要です。  


- **Harayoki MSX1 Effect(C++/AEプラグイン)** – 既述のMSX1PaletteQuantizerと同一エンジンのAfterEffects/プレミア向けプラグイン版(MIT)【31†L24-L26】。GPU非対応ながらリアルタイムプレビューも可能。  


  *評価:* 大規模映像作品向けで、画像1枚単位の連続変換には向かない。MSX制約を忠実に再現し、色補正オプションも豊富です【31†L41-L42】。  


- **(参考)Shadertoy上のMSX風シェーダ** – ShaderToyなどに投稿された「MSXっぽいピクセル描画」のサンプルコードがあります(ユーザーによる自作例)。公式ドキュメントはありませんが、16色やディザを用いたリアルタイム効果が試せます。  


  *評価:* インタラクティブなデモ用途には面白いですが、コードは公開場所依存でフォークが難しく、製品への流用も不向きです。  


- **(参考)Canvas手描きフィルタ例** – HTML5 Canvasでピクセル単位に色情報を操作し、MSXパレット制約に合わせて手動処理するアプローチ(JavaScriptでImageDataを操作)。公開ライブラリは少ないものの、自作も可能です。  


  *評価:* フレームワーク不要で自由度高い反面、自前でMSXルール実装が必要で開発コスト高。  


## 比較表(主要8件)


| 名称/ソース                         | パレット精度 | ディザリング          | スキャンライン | 8ドット2色制限 | スプライト再現 | 使い勝手         | ライセンス     |

|:-------------------------------------|:------------|:---------------------|:--------------|:---------------|:--------------|:---------------|:-------------|

| **MMSXX_MSX1PaletteQuantizer** (Harayoki,C++)【31†L24-L26】【31†L41-L42】 | ◎ 実機15色に準拠 | ◎ (HSBベース誤差拡散) | –            | ◎ (実装済)   | –             | 高機能だがC++/Win必須 | MIT【31†L24-L26】 |

| **Harayoki MSX1 Effect (AE用プラグイン)**【31†L24-L26】【31†L41-L42】 | 同上         | 同上                | –            | ◎ (実装済)   | –             | AE/Premiere上で可  | MIT【31†L24-L26】 |

| **Phaser MSXパレット** (JS)【38†L348-L357】      | ◯ Phaser版16色       | × なし               | –            | × なし          | –             | Phaser導入前提     | MIT【38†L328-L332】 |

| **Construct3 PX_MSXフィルタ**【78†L398-L402】     | ◯ MSX風色16色       | × (不明)           | –            | × なし          | –             | Constructで即使用可 | 独自商用       |

| **RgbQuant.js (JS)**【84†L262-L270】     | △(任意パレット指定可) | △(誤差拡散可)      | –            | × なし          | –             | 汎用量子化ライブラリ | MIT【84†L262-L270】 |

| **glfx.js (JS/WebGL)**【92†L278-L280】  | △(HSL調整等のみ)  | × なし               | –            | × なし          | –             | GLエフェクト多数   | MIT【92†L278-L280】 |

| **Shadertoy MSXデモ例**            | △(コード次第)     | △(例あり)         | –            | △(任意実装可)  | –             | 研究・デモ向き      | ?(作者依存)   |

| **手作りCanvasフィルタ例**         | △(実装次第)      | △(実装次第)       | –            | △(実装次第)   | –             | 自由だが作業負荷大  | –             |


- ※パレット精度:実機色再現度(◎=ほぼ実機準拠、◯=近似、△=実装次第)。  

- ※スプライト再現:いずれもスプライト制約は未再現(全候補×)。  


本調査では、純粋なJavaScript/Canvas/WebGL実装のMSX1専用フィルタはほぼ見当たりませんでした。主にHarayoki氏のC++ベースツールが最も再現性が高く、PhaserやConstructの機能を組み合わせる方法が続く形です。用途や開発環境に応じて、商用ツールや既存ライブラリを活用しつつ、足りない部分を自作補完するのが実践的と考えられます。  


**参考資料:** Harayoki氏のMSX1フィルタ解説記事【8†L37-L44】【31†L24-L26】【31†L41-L42】、Phaser公式ドキュメント【38†L348-L357】、Constructアセット説明【78†L398-L402】、RgbQuant.js GitHub【84†L262-L270】など。

Richard Feynmanが「自然をシミュレーションする計算機」というアイデアを発表したMITワークショップは、1981年5月6~8日にMITエンディコット・ハウスで開催された「Physics of Computation」会議でした

 # 調査結果サマリー  

Richard Feynmanが「自然をシミュレーションする計算機」というアイデアを発表したMITワークショップは、1981年5月6~8日にMITエンディコット・ハウスで開催された「Physics of Computation」会議でした【32†L57-L60】。Feynman自身の論文には講演原稿が「**Received May 7, 1981**」と記されており【48†L12-L14】、少なくとも5月7日までに講演は行われたことが分かります(一般記事も「5月6~8日開催」と報じています【19†L68-L71】)。しかし、公開資料には講演の具体的な日付は明記されていません。**結論**としては、講演は1981年5月の会議中(おそらく5月7日)に行われたと推定できますが、公式記録が残らないため単一日付の確証は得られません。したがって最良の推定日付は「1981年5月6~8日(5月7日頃)」で、確度はやや高いものの100%の断定はできない、という評価になります。  


【32†embed_image】MIT主催の会議記録には「Physics of Computation」会議が**1981年5月6日から8日**に開催されたと明記されています【32†L57-L60】。この公式報告によって会議の日程範囲は確定しています。また、Feynmanの論文冒頭には講演要旨が「Received May 7, 1981」と記録され【48†L12-L14】、講演が会期2日目(5月7日)に行われた可能性を示唆します。これらより、**会議は1981年5月6~8日**、**Feynmanの講演はその期間内**であったことが分かります。一方、当時のプログラムや議事録等では講演の日付が具体的に示されておらず、会議初日か2日目かも明確でありません。現存資料の範囲では単一日付の確認はできず、**最大限示せる日時は「1981年5月6~8日(5月7日頃)」**という結論になります。  


## 証拠タイムライン  


| 日付・期間           | 出典・資料                              | 引用・抜粋例                                                     | 信頼度(メモ)      |

|:----------------:|:---------------------------------:|:------------------------------------------------------------|:---------------|

| **1981年5月6–8日** | 物理情報理論雑誌(IJTP, 1982年)会議序文   | “The *Physics of Computation* conference was held on **May 6–8, 1981** at MIT’s Endicott House…”【32†L57-L60】 | 高 (公式一次資料) |

| **1981年5月6–8日** | FastCompany誌(2021年記事)                | “*The Physics of Computation…* was held from **May 6 to 8, 1981**…”【19†L68-L71】          | 中 (報道記事)     |

| **1981年5月7日**   | Feynman『Simulating Physics…』論文 (1982年) | 論文冒頭で “Received May 7, 1981” と記載【48†L12-L14】                             | 高 (一次論文)     |

| **1981年5月**      | Alsingらによる論説 (arXiv, 2024年)         | “Feynman delivered his lecture… at MIT Endicott House in **May of 1981**.”【16†L21-L24】    | 中 (二次資料)     |


上表のように、**一次資料**(会議報告やFeynman論文)では会議の開催期間と論文受領日を明示しています【32†L57-L60】【48†L12-L14】。これらはもっとも信頼度の高い証拠です。一方、ネット記事【19†L68-L71】や後年の解説【16†L21-L24】も同様に「1981年5月」開催と述べていますが、具体的な日付ではありません。いずれの資料にも講演当日の明記はなく、**プログラムや議事録の欠落**により日付の特定に至っていません。  


## 調査手順と探索経緯  

1. **検索エンジンによる文献探索**:まずGoogle等で“1981 MIT Physics of Computation”などのキーワード検索を行い、会議名や関係者(Feynman, Fredkin, Bennettなど)でヒットを調査しました。  

2. **会議記録(一次資料)の確認**:国際理論物理学雑誌(IJTP)1982年号に掲載された「Physics of Computation」特集(Fredkinら編集)の序文や論文を発見しました。序文に会議日程が明記され【32†L57-L60】、Feynman論文には論文受領日が「1981年5月7日」と記されていました【48†L12-L14】。これらから会議開催期間とFeynman講演の時期を推定しました。  

3. **参加者・目撃者の記録**:物理学者Charlie Bennettらによる記事や回顧録、新聞記事(FastCompany誌2021年記事)にて会議日程の記述を確認し【19†L68-L71】、先の一次資料と一致することを確かめました。加えてAlsingらの近年の論文【16†L21-L24】でも「1981年5月に開催」と触れていました。  

4. **Feynman関連資料の検討**:Caltechやプリンストンに所蔵されるFeynman個人文書をWeb検索しましたが、1981年当時の未発表メモや日記などは見つかりませんでした。1982年の論文発表日や会議参加記録を参照し、発表直前までに講演があったと推測しています。  


以上の検討から、公式記録と報道の両方で会議が「1981年5月6~8日」とされていることが判明し【32†L57-L60】【19†L68-L71】、Feynmanの論文受領日(5月7日)がこれを補強します【48†L12-L14】。しかし、**講演日が特定できる直接証拠は見つかっていない**ため、日付は5月中の範囲として扱わざるを得ません。


## 未解決の場合の今後の調査方針  

現状の資料では明確な**講演単日付**は得られていません。さらなる調査手段として以下が考えられます:  


- **MITアーカイブへの照会**:MITインスティテュート・アーカイブやMITコンピュータ科学研究所(当時)の資料庫に、会議プログラムや日程表が保存されている可能性があります。特に「Physics of Computation Conference 1981」関連の文書を検索し、(仮に「プログラム & 講演要旨集」のようなファイル名で)当時の資料を確認します。  

- **エンディコット・ハウス記録**:会場であるMITエンディコット・ハウスの運営部門(または関係記録)に、1981年春の会議開催記録が残っていないか調べる。予約記録やバッジリスト等があれば講演者・日程が分かる可能性があります。  

- **Feynman個人文書の精査**:Caltechやプリンストン大学に所蔵されるリチャード・P・ファインマン文書コレクション(手稿、講演ノート、往復書簡など)から、1981年5月に関する記録を探します。旅行日程表や講演準備メモ、同僚への報告などがあれば、具体的な講演日が判明するかもしれません。  

- **参加者・主催者の記録**:Edward FredkinやRolf Landauer、Tom Toffoliら会議主催者、並びに参加した人物(例:Charlie Bennett, Paul Benioff, Freeman Dyson, John Wheelerなど)の所蔵文書・回想録を調べます。例えばIBM研究所や関係機関(カーネギーメロン大、ボストン大など)に同様の会議資料が保管されている可能性があります。  

- **関連刊行物・ニュース速報**:当時の専門誌(Physics Today, IEEE Spectrum 1981年号など)やプレスリリースで、会議報告や講演サマリーが掲載されていないか確認します。また、会議直後の新聞(ボストン・グローブ等)記事にも着目します。  


以上の追加調査により、講演の具体的な日時を記した一次資料や参照が見つかれば、日付の確定が可能になるかもしれません。


```mermaid

timeline

    title Feynman 1981年MIT会議の経過

    1981-05-06 : 会議(Physics of Computation)開始

    1981-05-07 : 会議2日目(Feynman講演実施と考えられる)

    1981-05-08 : 会議終了

```  


**参考資料:** 1982年の会議報告論文【32†L57-L60】【48†L12-L14】、FastCompany報道【19†L68-L71】、アルシング他による総説【16†L21-L24】など。