▶ 実 行
▶ 実行
クリア
ダイスタワー(ThreeJS+AmmoJS)
by てぃふと@うぇいく
!「https://n3s.nadesi.com/plain/plugin_weykthree.js」を取り込む !「https://n3s.nadesi.com/plain/plugin_weykammo.js」を取り込む AMOベースURL=「https://weyk.sakura.ne.jp/storage/ammojs」 # 長さの単位をcmといて扱う。重力加速度を98とすることで時間とのスケールを合わせる。 # 質量はキログラム単位。 # 床を突き抜けるようなら、サイコロを大きくするか床を厚くする。 サイコロ個数は10 床辺長は50 # 50cm四方(50m×50m×20cm) 床厚は0.2 # 2mm サイコロ辺長は1.5 # 1.5cm角 サイコロ質量は15 # 15kg 重力は98 # 98cm/s^2 壁高は50 #衝突時に跳ね返りはぶつかったもの同士での反発率の積で決まります。 #積が1.0を超える場合、ぶつかる勢いより跳ね返る勢いが強くなります(総エネルギーが増加する) 床反発率は0.7 # 黄色い地面 壁反発率は0.7 # 黄色い地面の外周にある見えない壁 サイコロ反発率は0.8 # サイコロ自身。全て、この値との積になる。 トレイ反発率は0.5 # ダイスタワー手前側のトレイ部分 タワー反発率は0.8 # ダイスタワー奥側のタワー部分(ガラス除く) ガラス反発率は1.0 # ダイスタワーのガラス部分 釘反発率は1.2 # 板でランダム化しているため未使用。 # 衝突判定の許容誤差(距離) 衝突マージンは0.001 # 0.1mm WEBGLキャンバスはNULL レンダラはNULL ココはNULL カメラはNULL 環境描画対象はNULL 環境カメラはNULL ガラス素材はNULL 板ガラスはNULL 物理ワールドはNULL 前回タイムスタンプは0 床はNULL 床鋼体はNULL # Ammo適用用 変動物リストは空配列 # レイキャスタ用 レイ対象リストは空配列 鋼体索引は{} ワールドマトリクスワークはNULL レイキャスタはNULL 表示済みはオフ 出目方向は[ [ 0, 0, 1], [ 1, 0, 0], [ 0,-1, 0], [ 0, 1, 0], [-1, 0, 0], [ 0, 0,-1] ] 開始する ●ライブラリ準備とは TJSライブラリ読み込み後には プラグイン準備 ここまで ここまで ●プラグイン準備とは ["controls/OrbitControls.js", "libs/ammo.wasm.js"]をTJSプラグイン読み込み後には AMMOライブラリ準備 ここまで ここまで ●AMMOライブラリ準備とは AMOライブラリ読込後には 準備完了 ここまで ここまで ●準備完了とは WEBGLキャンバス要素準備 描画準備 レイキャスタはTJSレイキャスタ作成 描画中キャンバスの「click」に「キャンバスクリック」をDOMイベント追加する 0でアニメート ここまで ●WEBGLキャンバス要素準備とは WEBGLキャンバスは"#three_cv"のDOM要素取得 もし、WEBGLキャンバスでなければ、 Pは描画中キャンバス["parentNode"] WEBGLキャンバスは"CANVAS"のDOM要素作成 WEBGLキャンバス["id"]は"three_cv" WEBGLキャンバス["width"]は描画中キャンバス["width"] WEBGLキャンバス["height"]は描画中キャンバス["height"] WEBGLキャンバス["style"]["display"]は「none」 PにWEBGLキャンバスをDOM子要素追加 ここまで ここまで ●後始末とは 描画中キャンバスの「mousedown」から「キャンバスクリック」をDOMイベント削除する ここまで ●キャンバスクリックとは もし、表示済みならば、 表示済みはオフ サイコロロールする ここまで ここまで # 基本単位に従いものを配置する。 # この世界では、長さはメートル、重さはキログラム、時間は秒で指定する。 # ただし、あまり細かい数値はうまく扱えない。 ●描画準備とは # 物理エンジンの空間(力学ワールド)を準備 # 物理ワールドは標準鋼体ワールド作成 # 表示するためのシーンを準備 # ココは、TJSシーン作成 ココに0x004400をTJS背景設定 # カメラを準備 # カメラは、[45,WEBGLキャンバス["width"]/WEBGLキャンバス["height"],0.05,80]のTJS透視投影カメラ作成 カメラを[2,50,-25]にTJS位置設定 カメラを[0,10,0]にTJS視点設定 カメラを"+Y"にTJSカメラ上方設定 ココにカメラをTJS登場 カメラのTJS投影マトリクス更新 環境描画対象は512を{ format: THREE["RGBFormat"], generateMipmaps: (1=1), minFilter: THREE["LinearMipmapLinearFilter"], encoding: THREE["sRGBEncoding"] }でTJS環境撮影用レンダーターゲット作成 環境カメラは[0.05,200,環境描画対象]のTJS環境撮影カメラ作成 # ガラス材質を作成 ガラス素材は{ color: 0xcccccc, side: THREE["DoubleSide"], envMap: 環境描画対象["texture"], reflectivity: 1, combine: THREE["MultiplyOperation"], opacity: 0.3, transparent: (1=1)}のTJS基本表面材質作成 # 床を生成する # # 床の見た目 床材は{"幅":床辺長,"高":床厚,"奥行":床辺長,バッファ:オン}のTJS箱作成 床素材は{color: 0xffff00}のTJS拡散反射材質作成 床は床材と床素材のTJSメッシュ作成 床にオンをTJS影受設定 床をココにTJS登場 # 床の物理エンジン空間の実体 形状は[床辺長÷2,床厚÷2,床辺長÷2]でAMO箱形状作成 形状に衝突マージンをAMOマージン設定 床鋼体は床から形状の0でMESH付鋼体作成 床鋼体に床反発率でAMO反発係数設定 物理ワールドに床鋼体をAMO鋼体追加 # 壁を物理エンジン空間に配置。表示はしない。側面の四方を囲む。 形状は[床辺長÷2,壁高÷2,床厚÷2]でAMO箱形状作成 形状に衝突マージンをAMOマージン設定 マトリクスはAMO変形マトリクス作成 マトリクスをAMO単位行列設定 マトリクスに[0, 壁高÷2, 床辺長÷2]をAMO原点設定 壁鋼体はマトリクスから形状の0でMESH無鋼体作成 壁鋼体に壁反発率でAMO反発係数設定 物理ワールドに壁鋼体をAMO鋼体追加 マトリクスはAMO変形マトリクス作成 マトリクスをAMO単位行列設定 マトリクスに[0, 壁高÷2, (-床辺長÷2)]をAMO原点設定 壁鋼体はマトリクスから形状の0でMESH無鋼体作成 壁鋼体に壁反発率でAMO反発係数設定 物理ワールドに壁鋼体をAMO鋼体追加 形状は[床厚÷2,壁高÷2,床辺長÷2]でAMO箱形状作成 形状に衝突マージンをAMOマージン設定 マトリクスはAMO変形マトリクス作成 マトリクスをAMO単位行列設定 マトリクスに[床辺長÷2, 壁高÷2, 0]をAMO原点設定 壁鋼体はマトリクスから形状の0でMESH無鋼体作成 壁鋼体に壁反発率でAMO反発係数設定 物理ワールドに壁鋼体をAMO鋼体追加 マトリクスはAMO変形マトリクス作成 マトリクスをAMO単位行列設定 マトリクスに[(-床辺長÷2), 壁高÷2, 0]をAMO原点設定 壁鋼体はマトリクスから形状の0でMESH無鋼体作成 壁鋼体に壁反発率でAMO反発係数設定 物理ワールドに壁鋼体をAMO鋼体追加 ダイスタワーはダイスタワー作成 ココにダイスタワーをTJS登場 # サイコロの各面の画像を非表示のキャンバスに準備 # サイコロ画像はサイコロ画像作成する。 サイコロテクスチャは{CANVAS:サイコロ画像}をTJSキャンバステクスチャ作成 # さいころを指定の個数生成する # 立方体部品はサイコロ辺長と(サイコロ辺長*0.1)のサイコロ構造作成 立方体平面部品は立方体部品[0] 立方体縁角部品は立方体部品[1] 立方体平面部品のTJS境界球計算 立方体平面素材は{ map:サイコロテクスチャ }のTJS拡散反射材質作成 もし、立方体縁角部品≠NULLならば、 立方体縁角部品のTJS境界球計算 立方体縁角素材は{ color: 0xffffffff }のTJS拡散反射材質作成 ここまで 形状は[サイコロ辺長÷2,サイコロ辺長÷2,サイコロ辺長÷2]でAMO箱形状作成 形状に衝突マージンをAMOマージン設定 (サイコロ個数)回繰り返す Nは回数-1 # さいころの見た目 立方はTJSグループ作成 立方体平面は立方体平面部品と立方体平面素材のTJSメッシュ作成 立方体平面にオンをTJS影受設定 立方体平面にオンをTJS影投設定 立方に立方体平面をTJS登場 レイ対象リストに立方体平面を配列追加 もし、立方体縁角部品≠NULLならば、 立方体縁角は立方体縁角部品と立方体縁角素材のTJSメッシュ作成 立方体縁角にオンをTJS影受設定 立方体縁角にオンをTJS影投設定 立方に立方体縁角をTJS登場 レイ対象リストに立方体縁角を配列追加 ここまで Xは0+((N%2)*2-1)*3 Yは30+((N/4)の整数部分)*1 Zは5+((((N%4)/2)の整数部分)*2-1)*1 立方を[X,Y,Z]にTJS位置設定 ココに立方をTJS登場 # レイキャスタでのレイ判定対象の一覧を準備する # さいころの物理エンジン空間の実体 立方体鋼体は立方から形状のサイコロ質量でMESH付鋼体作成 X回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) Y回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) Z回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) 立方体鋼体に[X回転, Y回転, Z回転]をAMO回転速度設定 立方体鋼体にサイコロ反発率でAMO反発係数設定 物理ワールドに立方体鋼体をAMO鋼体追加 # さいころは動くので一覧に入れて管理する 変動物リストに{表示体:立方, 鋼体:立方体鋼体}を配列追加する 鋼体索引[立方["id"]]は立方体鋼体 ここまで # 光源を準備 # # 全体をぼやっと照らす環境光源を生成 光は0x202020のTJS環境光源作成 ココに光をTJS登場 # 1方向から照らす平行光源を生成 太陽は[0xffffff, 1]のTJS平行光源作成 太陽を[5,50,-5]にTJS位置設定 太陽にオンをTJS影投設定 ココに太陽をTJS登場 太陽の["シャドー"]に[1024,1024]をTJSマップサイズ設定 太陽の["シャドー","カメラ"]に0.001をTJSカメラ最近距離設定 太陽の["シャドー","カメラ"]に100をTJSカメラ最遠距離設定 # 1点から射程内を照らすポイント光源を生成 #ランタンは[0xffffff, 2, 100, 1]のTJS点光源作成 #ランタンを[5,50,-5]にTJS位置設定 #ランタンにオンをTJS影投設定 #ココにランタンをTJS登場 #ランタンの["シャドー"]に[1024,1024]をTJSマップサイズ設定 #ランタンの["シャドー","カメラ"]に0.001をTJSカメラ最近距離設定 #ランタンの["シャドー","カメラ"]に100をTJSカメラ最遠距離設定 # 1点から対象をコーン状に照らすスポット光源(スポットライト)を生成 #スポットライトは[0xffffff, 2, 60, PI/3, 1, 1]のTJSスポット光源作成 #スポットライトを[10,30,-10]にTJS位置設定 #スポットライトにオンをTJS影投設定 #ココにスポットライトをTJS登場 #スポットライトの["シャドー"]に[1024,1024]でTJSマップサイズ設定 #スポットライトの["シャドー","カメラ"]に0.001をTJSカメラ最小距離設定 #スポットライトの["シャドー","カメラ"]に50をTJSカメラ最大距離設定 #スポットライトの["シャドー","カメラ"]にPI/3をTJSカメラ視野角設定 # ThreeJSの表示準備 # レンダラは'three_cv'にTJS描画準備 レンダラに[WEBGLキャンバス["width"],WEBGLキャンバス["height"]]をTJSサイズ設定 レンダラに0x000000をTJSクリア色設定 レンダラをTJS影処理有効 # ThreeJSのオービットコントロールを作成して適用 # # DOMには採取的に表示に使うキャンバスを指定する コントローラはカメラに描画中キャンバスのTJS衛星軌道コントローラ作成 ここまで ●サイコロロールとは Nは0 変動物リストを反復する 変動物は対象 鋼体は変動物["鋼体"] 表示体は変動物["表示体"] Xは0+((N%2)*2-1)*3 Yは30+((N/4)の整数部分)*1 Zは5+((((N%4)/2)の整数部分)*2-1)*1 X回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) Y回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) Z回転は((50の乱数)/25+2.5)*((2の乱数)*2-1) ワールドマトリクスワークにAMO単位行列設定 ワールドマトリクスワークに[X, Y, Z]をAMO原点設定 鋼体にワールドマトリクスワークをAMOワールド変換行列設定 (鋼体からAMO状態管理器取得)にワールドマトリクスワークをAMOワールド変換行列設定 鋼体をAMO力静止 鋼体に[0, 0, 0]をAMO移動速度設定 鋼体に[X回転, Y回転, Z回転]をAMO回転速度設定 鋼体を表示体に物体姿勢反映 鋼体をAMO活性化 NはN+1 ここまで ここまで # 辺長 角が丸くない状態での1辺の長さ # 角半径 1つの角の丸みの部分の半径 # 丸み角未実装のため、丸みを持たせると隙間が空きます。 ●(辺長と角半径の)サイコロ構造作成とは 結果は[NULL,NULL] # triangle_stripによる四角形をtrianglesに分解する際の参照順序 頂点順序は[0,1,2,2,1,3] # -1~+1に正規化した座標で平面部分の位置を求める 正点は((辺長÷2)-角半径)÷(辺長÷2) 負点は(-正点) # 256*128のサイズ上に64*64を3*2で配置されているのを想定 U0は0 U1は64*1/256 U2は64*2/256 U3は64*3/256 V0は0 V1は64*1/128 V2は64*2/128 # 起点[0,0,0]、縮退三角形抜きで1面4頂点で定義する # 前後左右上下の順 # 上記の頂点順に合わせてUVも定義する。 平面頂点リストは[ 負点, 正点, -1, U0, V0, 正点, 正点, -1, U1, V0, 負点, 負点, -1, U0, V1, 正点, 負点, -1, U1, V1, 正点, 正点, 1, U0, V1, 負点, 正点, 1, U1, V1, 正点, 負点, 1, U0, V2, 負点, 負点, 1, U1, V2, -1, 正点, 正点, U1, V0, -1, 正点, 負点, U2, V0, -1, 負点, 正点, U1, V1, -1, 負点, 負点, U2, V1, 1, 正点, 負点, U1, V1, 1, 正点, 正点, U2, V1, 1, 負点, 負点, U1, V2, 1, 負点, 正点, U2, V2, 負点, 1, 正点, U2, V0, 正点, 1, 正点, U3, V0, 負点, 1, 負点, U2, V1, 正点, 1, 負点, U3, V1, 負点, -1, 負点, U2, V1, 正点, -1, 負点, U3, V1, 負点, -1, 正点, U2, V2, 正点, -1, 正点, U3, V2 ] インデックスは空配列 6回繰り返す Iは(回数-1)*4 6回繰り返す JはI+(頂点順序[回数-1]) インデックスにJを配列追加 ここまで ここまで geoはTJS空構造作成 geoにインデックスをTJSインデックス設定 頂点配列は平面頂点リストのF32配列 bufは頂点配列から5でTJSインターリーブバッファ作成 bufに"有り"をTJS変更有無設定 attrはbufで0から3のTJSインターリーブ属性作成 geoの"position"にattrをTJS属性設定 attrはbufで3から2のTJSインターリーブ属性作成 geoの"uv"にattrをTJS属性設定 geoを[辺長÷2,辺長÷2,辺長÷2]にTJS拡大 geoのTJS法線計算 結果[0]はgeo # 縁の四角形の定義 # 手前の面の、上下左右 # 上の面の右左奥 # 右の面の下奥 # 左の面の下奥 # 奥の面の下 # 角の三角形の定義 # 手前の面の左上、右上、左下、右下 # 奥の面の左上、右上、左下、右下 # 常に手前も奥も手前から見た状態での左右(反転しない) 縁角頂点リストは[ 負点 1, 負点, 0, 1, 0, 正点 1, 負点, 0, 1, 0, 負点, 正点, -1, 0, 0, -1, 正点, 正点, -1, 0, 0, -1, 負点, 負点, -1, 0, 0, -1, 正点, 負点, -1, 0, 0, -1, 負点, -1, 負点, 0, -1, 0, 正点, -1, 負点, 0, -1, 0, 負点, 正点, -1, 0, 0, -1, 負点, 負点, -1, 0, 0, -1, -1, 正点, 負点, -1, 0, 0, -1, 負点, 負点, -1, 0, 0, 正点, 負点, -1, 0, 0, -1, 正点, 正点, -1, 0, 0, -1, 1, 負点, 負点, 1, 0, 0, 1, 正点, 負点, 1, 0, 0, 正点, 1, 負点, 0, 1, 0, 正点, 1, 正点, 0, 1, 0, 1, 正点, 負点, 1, 0, 0, 1, 正点, 正点, 1, 0, 0, 負点, 1, 正点, 0, 1, 0, 負点, 1, 負点, 0, 1, 0, -1, 正点, 正点, -1, 0, 0, -1, 正点, 負点, -1, 0, 0, 負点, 正点, 1, 0, 0, 1, 正点, 正点, 1, 0, 0, 1, 負点, 1, 正点, 0, 1, 0, 正点, 1, 正点, 0, 1, 0, 1, 負点, 負点, 1, 0, 0, 1, 負点, 正点, 1, 0, 0, 正点, -1, 負点, 0, -1, 0, 正点, -1, 正点, 0, -1, 0, 正点, 正点, 1, 0, 0, 1, 正点, 負点, 1, 0, 0, 1, 1, 正点, 正点, 1, 0, 0, 1, 負点, 正点, 1, 0, 0, -1, 負点, 正点, -1, 0, 0, -1, 負点, 負点, -1, 0, 0, 負点, -1, 正点, 0, -1, 0, 負点, -1, 負点, 0, -1, 0, 負点, 負点, 1, 0, 0, 1, 負点, 正点, 1, 0, 0, 1, -1, 負点, 正点, -1, 0, 0, -1, 正点, 正点, -1, 0, 0, 正点, 負点, 1, 0, 0, 1, 負点, 負点, 1, 0, 0, 1, 正点, -1, 正点, 0, -1, 0, 負点, -1, 正点, 0, -1, 0, 負点, 正点, -1, 0, 0, -1, -1, 正点, 負点, -1, 0, 0, 負点, 1, 負点, 0, 1, 0, 正点, 正点, -1, 0, 0, -1, 正点, 1, 負点, 0, 1, 0, 1, 正点, 負点, 1, 0, 0, 負点, 負点, -1, 0, 0, -1, 負点, -1, 負点, 0, -1, 0, -1, 負点, 負点, -1, 0, 0, 正点, 負点, -1, 0, 0, -1, 1, 負点, 負点, 1, 0, 0, 正点, -1, 負点, 0, -1, 0, 負点, 正点, 1, 0, 0, 1, 負点, 1, 正点, 0, 1, 0, -1, 正点, 正点, -1, 0, 0, 正点, 正点, 1, 0, 0, 1, 1, 正点, 正点, 1, 0, 0, 正点, 1, 正点, 0, 1, 0, 負点, 負点, 1, 0, 0, 1, -1, 負点, 正点, -1, 0, 0, 負点, -1, 正点, 0, -1, 0, 正点, 負点, 1, 0, 0, 1, 正点, -1, 正点, 0, -1, 0, 1, 負点, 正点, 1, 0, 0 ] インデックスは空配列 # 縁の部分(四角形)のインデックスを生成 12回繰り返す Iは(回数-1)*4 6回繰り返す JはI+(頂点順序[回数-1]) インデックスにJを配列追加 ここまで ここまで # 角の部分(三角形)のインデックスを生成 8回繰り返す Iは(回数-1)*3+4*12 3回繰り返す JはI+(回数-1) インデックスにJを配列追加 ここまで ここまで geoはTJS空構造作成 geoにインデックスをTJSインデックス設定 頂点配列は縁角頂点リストのF32配列 bufは頂点配列から6でTJSインターリーブバッファ作成 bufに"有り"をTJS変更有無設定 attrはbufで0から3のTJSインターリーブ属性作成 geoの"position"にattrをTJS属性設定 attrはbufで3から3のTJSインターリーブ属性作成 geoの"normal"にattrをTJS属性設定 geoを[辺長÷2,辺長÷2,辺長÷2]にTJS拡大 結果[1]はgeo 結果で戻る ここまで ●ダイスタワー作成とは # 各パーツを生成してGroupにまとめる # 現時点では、Groupは移動しない・回転しない(回転・座標がワールドと一致する)。 コレはTJSグループ作成 # 板素材を準備する # ローダは{パス:"https://n3s.nadesi.com/"}でTJSテクスチャローダ作成 色TEXはローダから「image.php?f=31.jpg」をTJS読み込み 視差TEXはローダから「image.php?f=32.jpg」をTJS読み込み ラフTEXはローダから「image.php?f=33.jpg」をTJS読み込み 法線TEXはローダから「image.php?f=35.jpg」をTJS読み込み 板素材は{map:色TEX,bumpMap:視差TEX,normalMap:法線TEX,roughnessMap:ラフTEX}のTJS標準材質作成 板素材["map"]["warpS"]はTHREE["RepeatWrapping"] 板素材["map"]["warpT"]はTHREE["RepeatWrapping"] # 底を生成する 構造は{"幅":10,"高":0.2,"奥行":20,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[0,0.1,0]にTJS位置設定 物["name"]は「トレイ」 物をコレにTJS登場 # トレイ部手前を生成する 構造は{"幅":10,"高":4,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[0,2.2,-9.9]にTJS位置設定 物["name"]は「トレイ」 物をコレにTJS登場 # トレイ部左側を生成する 物は構造と板素材のTJSメッシュ作成 物を[-4.9,2.2,-4.8]にTJS位置設定 物["rotation"]["y"]=PI/2 物["name"]は「トレイ」 物をコレにTJS登場 # トレイ部右側を生成する 物は構造と板素材のTJSメッシュ作成 物を[4.9,2.2,-4.8]にTJS位置設定 物["rotation"]["y"]=-PI/2 物["name"]は「トレイ」 物をコレにTJS登場 # タワー部奥側を生成する 構造は{"幅":10,"高":25,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[0,12.7,9.9]にTJS位置設定 物["name"]は「タワー」 物をコレにTJS登場 # タワー部左側を生成する 構造は{"幅":9.6,"高":25,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[-4.9,12.7,5]にTJS位置設定 物["rotation"]["y"]=PI/2 物["name"]は「タワー」 物をコレにTJS登場 # タワー部右側を生成する 物は構造と板素材のTJSメッシュ作成 物を[4.9,12.7,5]にTJS位置設定 物["rotation"]["y"]=-PI/2 物["name"]は「タワー」 物をコレにTJS登場 # タワー部手前側を生成する 構造は{"幅":9.6,"高":22,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造とガラス素材のTJSメッシュ作成 物を[0,15.7,0.4]にTJS位置設定 物["name"]は「ガラス」 物をコレにTJS登場 環境カメラを[0,15.7,0.4]にTJS位置設定 板ガラスは物 # 出口の板を生成する 構造は{"幅":9.6,"高":9,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[0,4,6]にTJS位置設定 物["rotation"]["x"]=PI*0.3 物["name"]は「タワー」 物をコレにTJS登場 # 入口の板を生成する 構造は{"幅":9.6,"高":8,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[0,22,4]にTJS位置設定 物["rotation"]["x"]=-PI*0.3 物["name"]は「タワー」 物をコレにTJS登場 # 内部板その1の板を生成する 構造は{"幅":6,"高":9.2,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[2.3,17,5.2]にTJS位置設定 物["rotation"]["x"]=PI/2 物["rotation"]["y"]=PI*0.2 物["name"]は「タワー」 物をコレにTJS登場 # 内部板その2の板を生成する 構造は{"幅":6,"高":9.2,"奥行":0.2,バッファ:オン}のTJS箱作成 物は構造と板素材のTJSメッシュ作成 物を[-2.3,12,5.2]にTJS位置設定 物["rotation"]["x"]=PI/2 物["rotation"]["y"]=-PI*0.2 物["name"]は「タワー」 物をコレにTJS登場 コレ["children"]を反復する 物は対象 鋼体は物からMESH鋼体作成 物["name"]で条件分岐する 「トレイ」ならば、 鋼体にトレイ反発率でAMO反発係数設定 ここまで 「タワー」ならば、 鋼体にタワー反発率でAMO反発係数設定 ここまで 「ガラス」ならば、 鋼体にガラス反発率でAMO反発係数設定 ここまで 「釘」ならば、 鋼体に釘反発率でAMO反発係数設定 ここまで ここまで 物理ワールドに鋼体をAMO鋼体追加 ここまで コレで戻る ここまで # アニメーションのループを構成する # 呼び出しごとの時間差の算出もここで行う ●(タイムスタンプで)アニメートとは もし、前回タイムスタンプが0でなければ、 経過秒は(タイムスタンプ-前回タイムスタンプ)÷1000 経過秒でワンフレーム ここまで 前回タイムスタンプはタイムスタンプ 画面更新時実行には(タイムスタンプ) タイムスタンプでアニメート ここまで ここまで # アニメーションの1フレーム分を処理する ●(経過秒で)ワンフレームとは # 力学ワールドの時間を経過時間分進める 物理ワールドを経過秒で10までAMO時間経過 # 力学ワールド上の鋼体の位置・姿勢を3Dモデル空間のモデルに反映する 変動物リストを反復する 表示体は対象["表示体"] 鋼体は対象["鋼体"] 鋼体を表示体に物体姿勢反映 ここまで 全停止チェック # 描画対象となるテクスチャは参照できないため、環境マップ取得時は非表示にしておく。 板ガラスをTJS非表示 レンダラにココを環境カメラでTJS環境カメラ撮影 板ガラスをTJS表示 レンダラにココをカメラでTJS描画 WEBGLキャンバスを[0,0]へ画像描画 ここまで # 力学ワールドで非活性になっているサイコロの数を数える。 # サイコロの総数と等しいなら全部が停止した状態でもう変化しない(ユーザクリック除く) # すべてのサイコロが停止した際、1度だけ出目を数えて表示する。 ●全停止チェックとは 停止数は0 変動物リストを反復する 鋼体は対象["鋼体"] もし、鋼体がAMO活性でなければ、 停止数は停止数+1 ここまで ここまで もし、停止数=サイコロ個数&&表示済み=オフならば、 表示済みはオン 出目合計は0 出目リストは空配列 変動物リストを反復する 表示体は対象["表示体"] 目は表示体の出目取得 出目リストに目を配列追加 出目合計は出目合計+目 ここまで 「出目は{出目リストを"+"で配列結合}={出目合計}でした。クリックでもう1度振ります。」を表示 ここまで ここまで # 指定した表示モデルがモデルにとってのどの軸がどの方向を向いているかをチェックし、 # +Y(上)となる方向をチェックすることで出目を判定する。 ●(表示体の)出目取得とは 最大Yは0 目は0 Iは0 QはTJS四元数作成 Qに表示体からTJSワールド四元数取得 出目方向を反復する Vは対象からTJSVec3 VにQをTJS四元数適用 もし、目=0||V["y"]>最大Yならば、 最大YはV["y"] 目はI+1 ここまで IはI+1 ここまで 目で戻る ここまで ●開始とは ライブラリ準備 ここまで # ThreeJS - Ammo 利用簡易支援 # ThreeJSのexamples/js/physics/AmmoPhysics.jsを参考に作成 # よくある組み合わせで力学ワールドを生成する ●標準鋼体ワールド作成とは CONFはAMOデフォルト衝突判定法作成 DISPはCONFのAMO衝突判定ディスパッチャ作成 BPHASEはAMODbvt作成 SOLVERはAMO物理ソルバー作成 ワールドは[DISP,BPHASE,SOLVER,CONF]でAMO離散力学ワールド作成 ワールドに[0,(-重力),0]でAMO重力設定 ワールドマトリクスワークはAMO変形マトリクス作成 ワールドで戻る ここまで # AmmoJSの鋼体の位置・姿勢をThreeJSのMESHに反映する ●(BODYをMESHに)物体姿勢反映とは 姿勢状態はBODYのAMO状態管理器取得 姿勢状態からワールドマトリクスワークにAMOワールド変換行列取得 位置はワールドマトリクスワークからAMO原点取得 回転はワールドマトリクスワークからAMO回転取得 MESHを位置にTJS位置設定 MESHを回転にTJS四元数設定 ここまで # ThreeJSのBoxGeometoryのMESHを情報を元に静的なAmmoJSの鋼体を作成する ●(MESHから)MESH鋼体作成とは 位置はMESHからTJS位置取得 回転はMESHからTJS四元数取得 構造はMESH["geometry"] パラメータは構造["parameters"] 構造["type"]で条件分岐する 「BoxGeometry」ならば、 Wは0.5 Hは0.5 Dは0.5 もし、パラメータ["width"]≠NULLならば、Wはパラメータ["width"]÷2 もし、パラメータ["height"]≠NULLならば、Hはパラメータ["height"]÷2 もし、パラメータ["depth"]≠NULLならば、Dはパラメータ["depth"]÷2 形状は[W,H,D]でAMO箱形状作成 ここまで 違えば、 「この鋼体作成はBox専用です。異なる形状は扱えません」でエラー発生 ここまで ここまで 形状に衝突マージンをAMOマージン設定 BODYはMESHから形状の0でMESH付鋼体作成 BODYで戻る ここまで # ThreeJSのMESHを情報を元にAmmoJSの鋼体を作成する ●(MESHからSHAPEのMASSで)MESH付鋼体作成とは 位置はMESHからTJS位置取得 回転はMESHからTJS四元数取得 マトリクスはAMO変形マトリクス作成 マトリクスをAMO単位行列設定 マトリクスに(位置からAMOVec3)をAMO原点設定 マトリクスに(回転からAMO四元数)をAMO回転設定 BODYはマトリクスからSHAPEのMASSでMESH無鋼体作成 BODYで戻る ここまで # 変換マトリクスから鋼体を作成する ●(マトリクスからSHAPEのMASSで)MESH無鋼体作成とは もし、MASSでなければ、 MASSは0 ここまで 状態管理器はマトリクスからAMOデフォルト状態管理器作成 慣性は[0,0,0]からAMOVec3 SHAPEにMASSと慣性でAMO局所慣性計算 構成情報は[MASS, 状態管理器, SHAPE, 慣性]からAMO鋼体構成情報作成 BODYは構成情報からAMO鋼体作成 BODYで戻る ここまで # 型付配列のヘルパー命令 ●(ARGの)UI8配列とは 『(function (a) {return new Uint8Array(a)})』を[ARG]でJS関数実行で戻る ここまで ●(ARGの)F32配列とは 『(function (a) {return new Float32Array(a)})』を[ARG]でJS関数実行で戻る ここまで # サイコロのテクスチャ用画像生成 # # サイコロ描画を使って、1-6の目を決まった位置に描く ●サイコロ画像作成とは 元キャンバスは描画中キャンバス CANVASは"CANVAS"のDOM要素作成 # テクスチャ用なので2のべき乗にする CANVAS["width"]は256 CANVAS["height"]は128 CANVASへ描画開始 [0,0]に64で1のサイコロ描画する [0,64]に64で6のサイコロ描画する [64,0]に64で2のサイコロ描画する [64,64]に64で5のサイコロ描画する [128,0]に64で3のサイコロ描画する [128,64]に64で4のサイコロ描画する 元キャンバスへ描画開始 CANVASで戻る ここまで # # 雪乃☆雫 作のイコロ3(canvasに角丸サイコロを描画)から。 # 目位置=[[4],[0,8],[0,4,8],[0,2,6,8],[0,2,4,6,8],[0,2,3,5,6,8]] ●(XYに辺長で数の)サイコロ描画とは X=XY[0]。Y=XY[1]。 r=8/60*辺長。r=0。 マス=辺長/4。目半径=辺長/10。 空に線色設定。白色に塗り色設定。3に線太さ設定。 もし、rが0ならば、 [X,Y,辺長,辺長]に四角描画。 違えば、 # [X,Y,辺長,辺長]に[r,r]の角丸四角描画。 ここまで もし、数が1ならば、目色は赤色。 違えば、目色は黒色。 目色に線色設定。目色に塗り色設定。1に線太さ設定。 (数)回 目x=1+目位置[数-1][回数-1]%3。 目y=1+目位置[数-1][回数-1]/3を整数変換。 [X+マス*目x,Y+マス*目y]に目半径の円描画。 ここまで。 ここまで。