「physics.js」による仮想物理実験室
3次元オブジェクトを配置しよう!

文責:遠藤理平
公開日:2017年03月03日
最終更新日:2017年03月03日

はじめに

 本項は「physics.js」を用いて物理シミュレーションを行うための手順をチュートリアル形式で紹介する記事です。 最新版「physics.js」(リビジョン14、2017年03月03日現在)をここからダウンロードしてください。以下はチュートリアルの目次です。

3次元オブジェクトの種類とクラス名

 仮想物理実験室に登場する物体を3次元オブジェクトと呼びことは前項(仮想物理実験室のつくりかた)にて少し触れました。 前項で登場した床オブジェクト、軸オブジェクトの他にも球オブジェクト、箱オブジェクトなど、現在の最新リビジョンで用意されている3次元オブジェクトは11種類です。それぞれの3次元オブジェクトを生成するためのクラスがそれぞれ用意されています。3次元オブジェクトの種類と外観、対応するクラスを列挙したものが次の表です。

(表)3次元オブジェクトの種類
3次元オブジェクト外観クラス名
床オブジェクト 床オブジェクト Floorクラス
軸オブジェクト 軸オブジェクト Axisクラス
球オブジェクト 球オブジェクト Sphereクラス
箱オブジェクト 箱オブジェクト Boxクラス
円柱オブジェクト 円柱オブジェクト Cylinderクラス
ポリゴンオブジェクト ポリゴンオブジェクト Polygonクラス
ばねオブジェクト ばねオブジェクト Springクラス
平面オブジェクト 平面オブジェクト Planeクラス
円オブジェクト 円オブジェクト Circleクラス
線オブジェクト 線オブジェクト Lineクラス
点オブジェクト 点オブジェクト Pointクラス

3次元オブジェクトの共通プロパティ

 仮想物理実験室に登場する3次元オブジェクトの状態は、JavaScriptのオブジェクト(データの集合体)のプロパティで管理されます。 このプロパティに値を与えることで3次元オブジェクトの位置や姿勢、色などは指定することができますこれらプロパティには3次元オブジェクトは種類に関わらずに定義される共通プロパティと、種類ごとに定義される固有プロパティが存在します。 次の表は主な共通プロパティの一覧です。共通プロパティは表の他にも多数存在しますので、今後必要に応じて解説していくことにします。

(表)主な共通プロパティ(一部)
プロパティ名 データ型 デフォルト 説明
posision <Vector3> {x:0, y:0, z:0} 位置ベクトル。
velocity <Vector3> {x:0, y:0, z:0} 速度ベクトル。
omega <Vector3> {x:0, y:0, z:0} 角速度ベクトル。
dynamic <bool> false 時間発展の有無を指定するブール値。
visible <bool> true 描画の有無を指定するブール値。非表示の場合でもオブジェクトの運動並びに衝突判定を行う。
draggable <bool> false 3次元オブジェクトのマウスドラックによる移動の有無を指定するフラグ。本フラグが立つ場合、マウスドラックによる演算に必要なバウンディングボックスが生成される。
allowDrag <bool> false 3次元オブジェクトのマウスドラックによる移動の許可を与えるフラグ。本フラグは、3次元オブジェクト生成時にdraggableプロパティがtrueと与えられている必要がある。
collision <bool> false 衝突判定の対象とするかを指定するブール値。
axis <Vector3> new THREE.Vector3 (0,0,1) 姿勢軸ベクトルの初期値。
angle <float> 0 回転角の初期値。
material <object> {
type : "Lambert",
shading : "Flat",
side : "Front",
color : 0xFF0000,
ambient : 0x990000,
opacity : 1.0,
transparent : false,
emissive : 0x000000,
specular : 0x111111,
shininess : 30,
castShadow : false,
receiveShadow : false,
depthWrite : true,
depthTest : true,
textureWidth : 256,
textureHeight : 256,
blending : null,
bumpScale : 0.05,
vertexColors: false
}
3次元オブジェクト材質関連パラメータを格納したプロパティ。
type : 材質の種類 ( "Basic" | "Lambert" | "Phong" | "Normal")
shading : シェーディングの種類 ( "Flat" | "Smooth" )
side : 描画する面 ( "Front" | "Back" | "Double")
color : 反射色(発光材質の場合:発光色)
ambient : 環境色
opacity : 不透明度
transparent : 透過処理
emissive : 反射材質における発光色
specular : 鏡面色
shininess : 鏡面指数
castShadow : 影の生成
receiveShadow : 影の映り込み
depthWrite : デプスバッファ書き込みの可否
depthTest : デプステスト実施の有無
textureWidth : 動的テクスチャ生成時の横幅
textureHeight : 動的テクスチャ生成時の縦幅
blending : ブレンディングの種類 ( "No" | "Normal" | "Additive" | "Subtractive" | "Multiply" | "Custo" )
bumpScale : バンプの大きさ
vertexColors: 頂点色利用の有無
boundingBox <object> {
visible : false,
color : null,
opacity : 0.2,
transparent : true,
draggFlag : false
}
バウンディングボックスの可視化関連パラメータを格納したプロパティ。
visible : 表示・非表示の指定
color : 発光色
opacity : 不透明度
transparent : 透過処理
draggFlag : マウスドラック状態かを判定するフラグ(内部)

基底クラス「PhysObjectクラス」について

 各種3次元オブジェクトを生成するクラスに共通プロパティを定義する方法について少しだけ詳しく解説します。 各種機能を持つ「クラス」という仕組みには、共通する機能をまとめた「クラス」から機能を引き継ぐという継承という仕組みが用意されています。 そして、引き継ぐ元となるクラスは基底クラス、基底クラスを継承したクラスは派生クラスと呼ばれます。 つまり、各種3次元オブジェクトに共通のプロパティは基底クラスとして用意されたPhysObjectクラスにて定義され、各々の3次元オブジェクトを生成するクラスはこのPhysObjectクラスを継承した派生クラスという形になります。
 PhysObjectクラスの詳細は後に解説を行います。


共通プロパティの指定方法

 共通プロパティの代表格である3次元オブジェクトの位置を指定してみましょう!前項で紹介したプログラムソース「stage.html」をテキストエディタで開いて軸オブジェクトを準備している箇所を見てください。Axisクラスで軸オブジェクトを生成と同時に、仮想物理実験室オブジェクトのobjectsプロパティ(配列)へ格納しています(※objectsプロパティに格納しないと実験室には登場しません)。 また、設定する3次元オブジェクトのパラメータは、コンストラクタを引数に渡すオブジェクトのプロパティに与えます。

【プログラムソース1】軸オブジェクトの準備(stage.html)
////////////////////////////////////////////////////////////////////
// 軸オブジェクトの準備
////////////////////////////////////////////////////////////////////
PHYSICS.physLab.objects.push(
	new PHYSICS.Axis({
		draggable: true,       //マウスドラックの有無
		allowDrag : true,      //マウスドラックの可否
		boundingBox : {
			visible : true,   //バウンディングボックスの可視化
			color : 0xFF00FF,  //バウンディングボックスの色
		},
		position :{ x: 0, y: 0, z: 3 },   //位置ベクトル
	})
);

3次元空間中の位置ベクトル:positionプロパティ

 3次元オブジェクトの位置はpositionプロパティにx,y,zをプロパティをもつオブジェクトを与えます(JavaScriptではオブジェクトのプロパティにオブジェクトを与えることも自由にできます)。 この値を変更して再実行(ウェブブラウザの再読込)してみてください。床面の市松模様の1枚分が長さ「1」です。意図したように移動できますでしょうか?

マウスドラックによる3次元オブジェクトの移動:draggableプロパティとallowDragプロパティ

 前項で紹介したプログラムソース「stage.html」を実行して気がついたと思いますが、この軸オブジェクトはマウスドラックで3次元空間中を移動させることができます。 このようなマウスドラックによる移動の有無と可否を設定するプロパティがdraggableプロパティallowDragプロパティです。draggableプロパティは3次元オブジェクトの生成時にマウスドラックするために必要な準備を行うかを指定するフラグです(trueあるいはfalseを与える)。そのため、3次元オブジェクトをマウスドラックで動かすことを想定している場合にはtrueを与えます。一方のallowDragプロパティはマウスドラックの可否を指定するフラグで、trueが与えられている間だけマウスドラックを行うことができます。状況に応じてtrueとfalseを切り替えることでマウスドラックの可否を制御することができます。
 allowDragをfalseに変更してみてください。マウスドラックができなくなると思います。

バウンディングボックス:boundingBoxプロパティ

 軸オブジェクトの上にマウスポインタを乗せたときに、半透明の箱が表示されたと思います。これは下図のようにマウスドラック可能な3次元オブジェクトの上にマウスポインタを乗せたときに表示されるバウンディングボックス(境界箱)です。操作可能性を視覚的に理解させることができます。このバウンディングボックスの表示の有無や色を指定するプロパティがboundingBoxプロパティで、本プロパティのvisibleプロパティcolorプロパティでそれぞれ指定することができます。なお、バウンディングボックスは視覚的な効果のみを与えるため、非表示(visibleプロパティをfalseに指定)にしたとしてもマウスドラックの可否には影響を与えません
バウンディングボックスの表示の有無と色(※)をしてみてください。

(※)colorプロパティに与えられている「0xFF00FF」は16進数を表す数値です。はじめの「0x」は16進数を表すプレフィックス(接頭子)で、次の2文字「FF」が赤色、さらに次の2文字「00」が緑色、最後の2文字「FF」が青色を表わす数値です。16進数の「FF」は10進数の「255」を表し、各色とも16進数で「00」から「FF」までの256段階で表します。

(図1)バウンディングボックスの例

 本項では3次元オブジェクトの共通プロパティの設定例として、位置とマウスドラック関連について解説しました。共通プロパティはこの他にも多数存在しますので、今後必要に応じて解説していきます。