SlideShare une entreprise Scribd logo
1  sur  33
Télécharger pour lire hors ligne
物理エンジンを使って
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日木曜日

Contenu connexe

Similaire à 物理エンジンを使って 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
 

Plus de Kazuya Hiruma

Plus 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
 

Dernier

Dernier (7)

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 

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