SlideShare uma empresa Scribd logo
1 de 33
Baixar para ler offline
物理エンジンを使って
3Dに息を吹き込む

13年12月12日木曜日
自己紹介
• 面白法人カヤック
HTMLファイ部所属
比留間 和也

• 最近は3D/JS/Unityばかりで、
あんまりHTML書いてません;

13年12月12日木曜日
JavaScriptの
新しい教科書
本を書きました

13年12月12日木曜日
最近作ったもの

13年12月12日木曜日
Agenda
• 作ったもの紹介
• 物理エンジンの仕組み(超簡易)
• CANNON.jsで物理演算
• Three.jsのCSS3DRendererで3D
13年12月12日木曜日
CSSでレンダリングされた
ほんとに投げれるサイコロ
13年12月12日木曜日
http://hookmark.in/
13年12月12日木曜日
物理エンジンの仕組み
1. 剛体に外力(重力など)を働かせる
2. ブロードフェーズ(剛体同士の大まかな衝突検出)
3. ナローフェーズ(剛体同士の詳細な衝突検出)
4. 衝突応答
5. 剛体の更新
6. 1に戻る

13年12月12日木曜日
剛体に外力を働かせる
13年12月12日木曜日
ブロードフェーズ
13年12月12日木曜日
ブロードフェーズ
13年12月12日木曜日
ナローフェーズ
13年12月12日木曜日
衝突応答
13年12月12日木曜日
衝突応答
13年12月12日木曜日
剛体の更新
13年12月12日木曜日
CANNON.jsで
物理演算

13年12月12日木曜日
世界を作る

13年12月12日木曜日
//Create a CANNON world.
world = new CANNON.World();
//Set gravity.
world.gravity.set(0, -98.2, 0);
//Set a way of broad phase
world.broadphase =
new CANNON.NaiveBroadphase();

13年12月12日木曜日
剛体を作る

13年12月12日木曜日
//Define a shape of rigid body.
var box =
new CANNON.Box(
new CANNON.Vec3(
cubeSize, cubeSize, cubeSize));
//Create a rigid body.
var dice =
new CANNON.RigidBody(0.3/* mass */,
box);
//Set a position of rigid body.
dice.position.y = 50;
//Add a rigid body to a world.
world.add(dice);
13年12月12日木曜日
//Create a plane as a ground.
var plane = new CANNON.Plane();
//Create a ground with mass 0.
var ground =
new CANNON.RigidBody(0, plane);
//Rotate 90 degree. (as a ground)
ground.quaternion.setFromAxisAngle(
new CANNON.Vec3(1, 0, 0),
-Math.PI / 2);
//Add a rigid body to a world.
world.add(ground);

13年12月12日木曜日
Three.jsの
CSS3DRendererで3D

13年12月12日木曜日
地面を作る

13年12月12日木曜日
//Create a ground with CSS3DObject
var textureSize = 800;
var floorEle = doc.createElement('div');
floorEle.style.width = textureSize + 'px';
floorEle.style.height = textureSize + 'px';
floorEle.style.background = 'url(ground.png)
left top repeat';
floorEle.style.backgroundSize = textureSize /
20 + 'px ' + textureSize / 20 + 'px';
floorObj = new THREE.CSS3DObject(floorEle);
floorObj.position.fromArray([0, 0, 0]);
floorObj.rotation.fromArray([Math.PI/2,0,0]);
scene.add(floorObj);
13年12月12日木曜日
//Create a ground with CSS3DObject
var textureSize = 800;
var floorEle = doc.createElement('div');
floorEle.style.width = textureSize + 'px';
floorEle.style.height = textureSize + 'px';
floorEle.style.background = 'url(ground.png)
left top repeat';
floorEle.style.backgroundSize = textureSize /
20 + 'px ' + textureSize / 20 + 'px';
floorObj = new THREE.CSS3DObject(floorEle);
floorObj.position.fromArray([0, 0, 0]);
floorObj.rotation.fromArray([Math.PI/2,0,0]);
scene.add(floorObj);
13年12月12日木曜日
サイコロを作る

13年12月12日木曜日
var boxInfo, el, dice, info, img, face;
boxInfo = [{ url: '2.png', position: [-cubeSize,0,0], rotation:
[0,Math.PI/2,0] },
{ url: '5.png', position: [cubeSize,0,0], rotation: [0,-Math.PI/2,0] },
{ url: '1.png', position: [0,cubeSize,0], rotation: [Math.PI/
2,0,Math.PI] },
{ url: '6.png', position: [0,-cubeSize,0], rotation: [-Math.PI/
2,0,Math.PI] },
{ url: '3.png', position: [0,0,cubeSize], rotation: [0,Math.PI,0] },
{ url: '4.png', position: [0,0,-cubeSize], rotation: [0,0,0] }];
el = document.createElement('div');
el.style.width = cubeSize * 2 + 'px';
el.style.height = cubeSize * 2 + 'px';
dice = new THREE.CSS3DObject(el);
for (var i = 0; i < boxInfo.length; i++) {
info = boxInfo[i];
img = document.createElement('img');
img.width = cubeSize * 2;
img.src = info.url;
face = new THREE.CSS3DObject(img);
face.position.fromArray(info.position);
face.rotation.fromArray(info.rotation);
dice.add(face);
}
13年12月12日木曜日
var boxInfo, el, dice, info, img, face;
boxInfo = [{ url: '2.png', position: [-cubeSize,0,0], rotation:
[0,Math.PI/2,0] },
{ url: '5.png', position: [cubeSize,0,0], rotation: [0,-Math.PI/2,0] },
{ url: '1.png', position: [0,cubeSize,0], rotation: [Math.PI/
2,0,Math.PI] },
{ url: '6.png', position: [0,-cubeSize,0], rotation: [-Math.PI/
2,0,Math.PI] },
{ url: '3.png', position: [0,0,cubeSize], rotation: [0,Math.PI,0] },
{ url: '4.png', position: [0,0,-cubeSize], rotation: [0,0,0] }];
el = document.createElement('div');
el.style.width = cubeSize * 2 + 'px';
el.style.height = cubeSize * 2 + 'px';
dice = new THREE.CSS3DObject(el);
for (var i = 0; i < boxInfo.length; i++) {
info = boxInfo[i];
img = document.createElement('img');
img.width = cubeSize * 2;
img.src = info.url;
face = new THREE.CSS3DObject(img);
face.position.fromArray(info.position);
face.rotation.fromArray(info.rotation);
dice.add(face);
}
13年12月12日木曜日
var boxInfo, el, dice, info, img, face;
boxInfo = [{ url: '2.png', position: [-cubeSize,0,0], rotation:
[0,Math.PI/2,0] },
{ url: '5.png', position: [cubeSize,0,0], rotation: [0,-Math.PI/2,0] },
{ url: '1.png', position: [0,cubeSize,0], rotation: [Math.PI/
2,0,Math.PI] },
{ url: '6.png', position: [0,-cubeSize,0], rotation: [-Math.PI/
2,0,Math.PI] },
{ url: '3.png', position: [0,0,cubeSize], rotation: [0,Math.PI,0] },
{ url: '4.png', position: [0,0,-cubeSize], rotation: [0,0,0] }];
el = document.createElement('div');
el.style.width = cubeSize * 2 + 'px';
el.style.height = cubeSize * 2 + 'px';
dice = new THREE.CSS3DObject(el);
for (var i = 0; i < boxInfo.length; i++) {
info = boxInfo[i];
img = document.createElement('img');
img.width = cubeSize * 2;
img.src = info.url;
face = new THREE.CSS3DObject(img);
face.position.fromArray(info.position);
face.rotation.fromArray(info.rotation);
dice.add(face);
}
13年12月12日木曜日
時間を進める

13年12月12日木曜日
function updatePhysics() {
//Step to a next time.
world.step(timeStep);
//Copy a position of rigid body to a mesh.
if (diceRigid) {
diceRigid.position.copy(dice.position);
diceRigid.quaternion.copy(dice.quaternion);
diceRigid.position.copy(camera.position);
camera.position.y += 50;
camera.position.x += 100;
camera.lookAt(diceRigid.position.copy(new
THREE.Vector3(0, 0, 0)));
}
}

13年12月12日木曜日
もう一回見てみます
13年12月12日木曜日
ご清聴ありがとうご
ざいました

13年12月12日木曜日

Mais conteúdo relacionado

Semelhante a 物理エンジンを使って 3Dに息を吹き込む (8)

three.js はじめましょ
three.js はじめましょthree.js はじめましょ
three.js はじめましょ
 
Three.jsで3D気分
Three.jsで3D気分 Three.jsで3D気分
Three.jsで3D気分
 
セーラーソン振り返り
セーラーソン振り返りセーラーソン振り返り
セーラーソン振り返り
 
Bitter Sweet Javascript
Bitter Sweet JavascriptBitter Sweet Javascript
Bitter Sweet Javascript
 
XHR2 Wonder Land
XHR2 Wonder LandXHR2 Wonder Land
XHR2 Wonder Land
 
Parse introduction
Parse introductionParse introduction
Parse introduction
 
JavaScriptをまじめに考えました+
JavaScriptをまじめに考えました+JavaScriptをまじめに考えました+
JavaScriptをまじめに考えました+
 
Data Visualization meetup 2017
Data Visualization meetup 2017Data Visualization meetup 2017
Data Visualization meetup 2017
 

Mais de Kazuya Hiruma

Mais de Kazuya Hiruma (20)

MESONプロジェクトから学ぶこれからのAR開発に必要なこと
MESONプロジェクトから学ぶこれからのAR開発に必要なことMESONプロジェクトから学ぶこれからのAR開発に必要なこと
MESONプロジェクトから学ぶこれからのAR開発に必要なこと
 
PORTAL with Nreal in CES 2020 開発の学び @XR Hub
PORTAL with Nreal in CES 2020 開発の学び @XR HubPORTAL with Nreal in CES 2020 開発の学び @XR Hub
PORTAL with Nreal in CES 2020 開発の学び @XR Hub
 
ARグラスで 魅力的な絵作り
ARグラスで 魅力的な絵作りARグラスで 魅力的な絵作り
ARグラスで 魅力的な絵作り
 
AWE Nite ARKit3 Hackathon
AWE Nite ARKit3 HackathonAWE Nite ARKit3 Hackathon
AWE Nite ARKit3 Hackathon
 
レイマーチ入門勉強会資料
レイマーチ入門勉強会資料レイマーチ入門勉強会資料
レイマーチ入門勉強会資料
 
MESONで手がけたARアプリ AR Developer Meetup #2
MESONで手がけたARアプリ AR Developer Meetup #2MESONで手がけたARアプリ AR Developer Meetup #2
MESONで手がけたARアプリ AR Developer Meetup #2
 
みんなレイ飛ばしてる?
みんなレイ飛ばしてる?みんなレイ飛ばしてる?
みんなレイ飛ばしてる?
 
VRゲーム制作楽しいよ! @UnityおとなのLT大会
VRゲーム制作楽しいよ! @UnityおとなのLT大会VRゲーム制作楽しいよ! @UnityおとなのLT大会
VRゲーム制作楽しいよ! @UnityおとなのLT大会
 
ElminaAR - Unity x ARKit 入門Meetup
ElminaAR - Unity x ARKit 入門MeetupElminaAR - Unity x ARKit 入門Meetup
ElminaAR - Unity x ARKit 入門Meetup
 
今すぐ始められるモバイルVR〜あなたも今日からVRエンジニア〜
今すぐ始められるモバイルVR〜あなたも今日からVRエンジニア〜今すぐ始められるモバイルVR〜あなたも今日からVRエンジニア〜
今すぐ始められるモバイルVR〜あなたも今日からVRエンジニア〜
 
UnityでARKitハンズオン
UnityでARKitハンズオンUnityでARKitハンズオン
UnityでARKitハンズオン
 
すぐそこにある未来〜AR〜
すぐそこにある未来〜AR〜すぐそこにある未来〜AR〜
すぐそこにある未来〜AR〜
 
VRで酔わないコンテンツ作り
VRで酔わないコンテンツ作りVRで酔わないコンテンツ作り
VRで酔わないコンテンツ作り
 
WebVRコンテンツ制作入門
WebVRコンテンツ制作入門WebVRコンテンツ制作入門
WebVRコンテンツ制作入門
 
WebVRってこんなことできるよ!
WebVRってこんなことできるよ!WebVRってこんなことできるよ!
WebVRってこんなことできるよ!
 
そしてWebVR
そしてWebVRそしてWebVR
そしてWebVR
 
Unity入門ハンズオン
Unity入門ハンズオンUnity入門ハンズオン
Unity入門ハンズオン
 
WebVR 酔いづらいコンテンツの作り方
WebVR 酔いづらいコンテンツの作り方WebVR 酔いづらいコンテンツの作り方
WebVR 酔いづらいコンテンツの作り方
 
WebVRことはじめ
WebVRことはじめWebVRことはじめ
WebVRことはじめ
 
集まっTail #5 LT
集まっTail #5 LT集まっTail #5 LT
集まっTail #5 LT
 

Último

2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
ssuserbefd24
 

Último (12)

論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
 
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
 
Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )
 
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
 
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
 
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
 
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
 
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
 
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
 
20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
 

物理エンジンを使って 3Dに息を吹き込む