Oculus+Node.js+Three.jsはVRの世界を作ります.
13073 ワード
Oculus+Node.js+Three.jsはVRの世界を作ります.
Oculus Riftは電子ゲームのために設計されたヘッドセットディスプレイです.これは仮想現実装置である.この設備は未来の人々のゲームの方式を変える可能性があります.
金曜日のHackday Showcaseの時に、ちょっとヒントができました.会社に休んでいたOculus DK 2を家に借りました.もうほこりだらけです.
一晩の開発環境の構築を試みた後、原生応用の開発を断念しました.一つは自分のコンピュータ(Raspberry Pi IIは計算しないと)ではないです.Windowsがなく、GNU/Linuxがなく、もう一つは会社のコンピューターはMac OSです.組み込み開発とゲーム開発にとって、Mac OSはまるで携帯電話の中のWindows Phone――ピット父のLLVM、GCC(Mac OS)、OpenGL、OLPlus、C+11です.また、Mac OSやLinuxに対する公式のSDKの支持は何世紀も遅れています.
結局、やはりWebの開発環境は構築しやすいです.このrepoの最後の効果図は以下の通りです.
効果: WASD制御前進、後退など. 回転ヘッド=リアルな世界. 付加効果:長く見たらめまいがします. これから、構築を始めましょう.
Node Oculus Services
ここで、私たちがやるべきことは、センサーを戻した四元の数(Quarternions)とオーラ角(Euler angles)をAPIの形で先端に戻すことです.
Node NMDのインストール
Node.jsにOculusというプラグインがあります.hmdは顔を頭に向けてディスプレイします.Oculus SDKのNodeインターフェースです.年代はもう古いですが、Mac OSとLinuxに対する公式のSDKはもう長い間更新されていません.
GNU/Linuxシステムでは、下のこれらのものをインストールする必要があります.
Node.js Oculus Hello,World
今からハロー、ワールドを書くことができます.直接に公式の例に来ます.
Node Oculus Websocket
ネットで見ましたhttp://laht.info/WebGL/DK2Demo.htmlこの仮想現実の映画は、WebSocketがあることを発見しましたが、Javaが書いたもので、参照コードとしてしか使えません.
今はこのようなWeb Servicesを書くことができます.まだExpress+Node.js+WSを使っています.
Thre.js+Oculus Effect+DK 2 Control
最後に次のような画面が必要です.
もちろん、Web VRというようなものをインストールしていたら、このような効果は必要ありません.タイトルの通り、Oculus Effectを使うと知っています.Three.jsのプラグインです.
以前のバージョンでは、Three.jsはすべてOculusのDemoを提供しています.もちろん見るだけです.そして相互作用のインターフェースはHTTPで、とても遊びにくいです.
Three.js DK 2 ontrolls
この時、私達は上から伝わってきた
(ps:copyがよくないなら、正しい言い方をしてください.高数の人を許してください.高校生の時だけ、これらの資料を見ました.)
Euler角は剛体の姿勢を記述するための一組の角度であり,Eulaは3次元の欧氏空間における剛体の任意の向きは3軸を回る回転再結合によって生成できると提案した.通常、3つの軸は互いに直交している.
対応する3つの角度はそれぞれroll(横転角)、pitch(仰向け角)とyaw(ヨー角)となり、上のpostionの中の3つの値です.
コードに変換します.
明確な観点から言えば、4元の数は複数の交換可能な拡張である.四元数の集合を多次元実数空間と考えると、四元数は複数に対して二次元空間である四次元空間を表している.
とにかく
コードを結合:
これは私に十分な理由があると信じています.Oculusは携帯電話+6軸スポーツ処理コンポーネントのアップグレードボードです.MPU 6050のようなセンサーを使ったことがあります.
Three.js DK 2 ontrolls
下のコードは私が書いたのではないですが、簡単に話してください.
私達は私達の初期化コードの中で私達のcontrolを初期化する必要があります.
Three.js KeyHandler
KeyHandlerはWeb開発に慣れた人にとっては簡単です.
おわりに
私が『RePractise前端編:前端演進史』で言ったように、これは新しい「先端」のようです.
Oculus Riftは電子ゲームのために設計されたヘッドセットディスプレイです.これは仮想現実装置である.この設備は未来の人々のゲームの方式を変える可能性があります.
金曜日のHackday Showcaseの時に、ちょっとヒントができました.会社に休んでいたOculus DK 2を家に借りました.もうほこりだらけです.
一晩の開発環境の構築を試みた後、原生応用の開発を断念しました.一つは自分のコンピュータ(Raspberry Pi IIは計算しないと)ではないです.Windowsがなく、GNU/Linuxがなく、もう一つは会社のコンピューターはMac OSです.組み込み開発とゲーム開発にとって、Mac OSはまるで携帯電話の中のWindows Phone――ピット父のLLVM、GCC(Mac OS)、OpenGL、OLPlus、C+11です.また、Mac OSやLinuxに対する公式のSDKの支持は何世紀も遅れています.
結局、やはりWebの開発環境は構築しやすいです.このrepoの最後の効果図は以下の通りです.
効果:
Node Oculus Services
ここで、私たちがやるべきことは、センサーを戻した四元の数(Quarternions)とオーラ角(Euler angles)をAPIの形で先端に戻すことです.
Node NMDのインストール
Node.jsにOculusというプラグインがあります.hmdは顔を頭に向けてディスプレイします.Oculus SDKのNodeインターフェースです.年代はもう古いですが、Mac OSとLinuxに対する公式のSDKはもう長い間更新されていません.
GNU/Linuxシステムでは、下のこれらのものをインストールする必要があります.
freeglut3-dev
mesa-common-dev
libudev-dev
libxext-dev
libxinerama-dev
libxrandr-dev
libxxf86vm-dev
Mac OSのインストールに失敗したら、Clangを使ってください.GCCのC標準ライブラリ(PS:Clang+GCCの混合体です.それらの間は複雑な関係です.):export CXXFLAGS=-stdlib=libstdc++
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
(PS:Mac OS El Captian+Xcode 7.0.2)clangバージョンは以下の通りです.Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
どうせ誤報があります.ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Service/Service_NetClient.o) was built for newer OSX version (10.7) than being linked (10.5)
ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Tracking/Tracking_SensorStateReader.o) was built for newer OSX version (10.7) than being linked (10.5)
ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Util/Util_ImageWindow.o) was built for newer OSX version (10.7) than being linked (10.5)
ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Util/Util_Interface.o) was built for newer OSX version (10.7) than being linked (10.5)
ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Util/Util_LatencyTest2Reader.o) was built for newer OSX version (10.7) than being linked (10.5)
ld: warning: object file (Release/obj.target/hmd/src/platform/mac/LibOVR/Src/Util/Util_Render_Stereo.o) was built for newer OSX version (10.7) than being linked (10.5)
[email protected] node_modules/node-hmd
でも、最後の行があれば十分です.Node.js Oculus Hello,World
今からハロー、ワールドを書くことができます.直接に公式の例に来ます.
var hmd = require('node-hmd');
var manager = hmd.createManager("oculusrift");
manager.getDeviceInfo(function(err, deviceInfo) {
if(!err) {
console.log(deviceInfo);
}
else {
console.error("Unable to retrieve device information.");
}
});
manager.getDeviceOrientation(function(err, deviceOrientation) {
if(!err) {
console.log(deviceOrientation);
}
else {
console.error("Unable to retrieve device orientation.");
}
});
運転する前に、まずあなたのOculusを連結してください.次のような結果があります.{ CameraFrustumFarZInMeters: 2.5,
CameraFrustumHFovInRadians: 1.29154372215271,
CameraFrustumNearZInMeters: 0.4000000059604645,
CameraFrustumVFovInRadians: 0.942477822303772,
DefaultEyeFov:
[ { RightTan: 1.0923680067062378,
LeftTan: 1.0586576461791992,
DownTan: 1.3292863368988037,
UpTan: 1.3292863368988037 },
{ RightTan: 1.0586576461791992,
LeftTan: 1.0923680067062378,
DownTan: 1.3292863368988037,
UpTan: 1.3292863368988037 } ],
DisplayDeviceName: '',
DisplayId: 880804035,
DistortionCaps: 66027,
EyeRenderOrder: [ 1, 0 ],
...
そして、私たちはリアルタイムでこれらのデータを返すことができます.Node Oculus Websocket
ネットで見ましたhttp://laht.info/WebGL/DK2Demo.htmlこの仮想現実の映画は、WebSocketがあることを発見しましたが、Javaが書いたもので、参照コードとしてしか使えません.
今はこのようなWeb Servicesを書くことができます.まだExpress+Node.js+WSを使っています.
var hmd = require("node-hmd"),
express = require("express"),
http = require("http").createServer(),
WebSocketServer = require('ws').Server,
path = require('path');
// Create HMD manager object
console.info("Attempting to load node-hmd driver: oculusrift");
var manager = hmd.createManager("oculusrift");
if (typeof(manager) === "undefined") {
console.error("Unable to load driver: oculusrift");
process.exit(1);
}
// Instantiate express server
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname + '/', 'public')));
app.set('views', path.join(__dirname + '/public/', 'views'));
app.set('view engine', 'jade');
app.get('/demo', function (req, res) {
'use strict';
res.render('demo', {
title: 'Home'
});
});
// Attach socket.io listener to the server
var wss = new WebSocketServer({server: http});
var id = 1;
wss.on('open', function open() {
console.log('connected');
});
// On socket connection set up event emitters to automatically push the HMD orientation data
wss.on("connection", function (ws) {
function emitOrientation() {
id = id + 1;
var deviceQuat = manager.getDeviceQuatSync();
var devicePosition = manager.getDevicePositionSync();
var data = JSON.stringify({
id: id,
quat: deviceQuat,
position: devicePosition
});
ws.send(data, function (error) {
//it's a bug of websocket, see in https://github.com/websockets/ws/issues/337
});
}
var orientation = setInterval(emitOrientation, 1000);
ws.on("message", function (data) {
clearInterval(orientation);
orientation = setInterval(emitOrientation, data);
});
ws.on("close", function () {
setTimeout(null, 500);
clearInterval(orientation);
console.log("disconnect");
});
});
// Launch express server
http.on('request', app);
http.listen(3000, function () {
console.log("Express server listening on port 3000");
});
つまり、連続して設備を発見するデータです.var data = JSON.stringify({
id: id,
quat: deviceQuat,
position: devicePosition
});
ws.send(data, function (error) {
//it's a bug of websocket, see in https://github.com/websockets/ws/issues/337
});
上の行のコメントは前に会った穴です.とにかくcalbackが必要です.Thre.js+Oculus Effect+DK 2 Control
最後に次のような画面が必要です.
もちろん、Web VRというようなものをインストールしていたら、このような効果は必要ありません.タイトルの通り、Oculus Effectを使うと知っています.Three.jsのプラグインです.
以前のバージョンでは、Three.jsはすべてOculusのDemoを提供しています.もちろん見るだけです.そして相互作用のインターフェースはHTTPで、とても遊びにくいです.
Three.js DK 2 ontrolls
この時、私達は上から伝わってきた
(Quaternions)とEuler anglesによって対応しなければなりません.{
"position": {
"x": 0.020077044144272804,
"y": -0.0040545957162976265,
"z": 0.16216422617435455
},
"quat": {
"w": 0.10187230259180069,
"x": -0.02359195239841938,
"y": -0.99427556991577148,
"z": -0.021934293210506439
}
}
オーラ角と四元の数(ps:copyがよくないなら、正しい言い方をしてください.高数の人を許してください.高校生の時だけ、これらの資料を見ました.)
Euler角は剛体の姿勢を記述するための一組の角度であり,Eulaは3次元の欧氏空間における剛体の任意の向きは3軸を回る回転再結合によって生成できると提案した.通常、3つの軸は互いに直交している.
対応する3つの角度はそれぞれroll(横転角)、pitch(仰向け角)とyaw(ヨー角)となり、上のpostionの中の3つの値です.
roll = (rotation about Z);
pitch = (rotation about (Roll • Y));
yaw = (rotation about (Pitch • Raw • Z));”
--「Oculus Rift Inアクション」から引くコードに変換します.
this.headPos.set(sensorData.position.x * 10 - 0.4, sensorData.position.y * 10 + 1.75, sensorData.position.z * 10 + 10);
四元数はアイルランドの数学者ウィリアム・ルージュ・ハミルトンが1843年に発見した数学概念です.明確な観点から言えば、4元の数は複数の交換可能な拡張である.四元数の集合を多次元実数空間と考えると、四元数は複数に対して二次元空間である四次元空間を表している.
とにかく
に使われる.コードを結合:
this.headPos.set(sensorData.position.x * 10 - 0.4, sensorData.position.y * 10 + 1.75, sensorData.position.z * 10 + 10);
this.headQuat.set(sensorData.quat.x, sensorData.quat.y, sensorData.quat.z, sensorData.quat.w);
this.camera.setRotationFromQuaternion(this.headQuat);
this.controller.setRotationFromMatrix(this.camera.matrix);
つまり、cameraとcontrolerの回転をセットする必要があります.これは私に十分な理由があると信じています.Oculusは携帯電話+6軸スポーツ処理コンポーネントのアップグレードボードです.MPU 6050のようなセンサーを使ったことがあります.
Three.js DK 2 ontrolls
下のコードは私が書いたのではないですが、簡単に話してください.
/*
Copyright 2014 Lars Ivar Hatledal
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
THREE.DK2Controls = function (camera) {
this.camera = camera;
this.ws;
this.sensorData;
this.lastId = -1;
this.controller = new THREE.Object3D();
this.headPos = new THREE.Vector3();
this.headQuat = new THREE.Quaternion();
var that = this;
var ws = new WebSocket("ws://localhost:3000/");
ws.onopen = function () {
console.log("### Connected ####");
};
ws.onmessage = function (evt) {
var message = evt.data;
try {
that.sensorData = JSON.parse(message);
} catch (err) {
console.log(message);
}
};
ws.onclose = function () {
console.log("### Closed ####");
};
this.update = function () {
var sensorData = this.sensorData;
if (sensorData) {
var id = sensorData.id;
if (id > this.lastId) {
this.headPos.set(sensorData.position.x * 10 - 0.4, sensorData.position.y * 10 + 1.75, sensorData.position.z * 10 + 10);
this.headQuat.set(sensorData.quat.x, sensorData.quat.y, sensorData.quat.z, sensorData.quat.w);
this.camera.setRotationFromQuaternion(this.headQuat);
this.controller.setRotationFromMatrix(this.camera.matrix);
}
this.lastId = id;
}
this.camera.position.addVectors(this.controller.position, this.headPos);
if (this.camera.position.y < -10) {
this.camera.position.y = -10;
}
if (ws) {
if (ws.readyState === 1) {
ws.send("get
");
}
}
};
};
WebSocketを開くと、常に最新のセンサー状態を取得し、udateを実行します.誰がudateメソッドを呼び出していますか?Thre.js私達は私達の初期化コードの中で私達のcontrolを初期化する必要があります.
var oculusControl;
function init() {
...
oculusControl = new THREE.DK2Controls( camera );
...
}
そしてどんどんudateメソッドを呼び出します.function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
oculusControl.update( clock.getDelta() );
THREE.AnimationHandler.update( clock.getDelta() * 100 );
camera.useQuaternion = true;
camera.matrixWorldNeedsUpdate = true;
effect.render(scene, camera);
}
最後に、該当するKeyHandlerを追加すればいいです.Three.js KeyHandler
KeyHandlerはWeb開発に慣れた人にとっては簡単です.
this.onKeyDown = function (event) {
switch (event.keyCode) {
case 87: //W
this.wasd.up = true;
break;
case 83: //S
this.wasd.down = true;
break;
case 68: //D
this.wasd.right = true;
break;
case 65: //A
this.wasd.left = true;
break;
}
};
this.onKeyUp = function (event) {
switch (event.keyCode) {
case 87: //W
this.wasd.up = false;
break;
case 83: //S
this.wasd.down = false;
break;
case 68: //D
this.wasd.right = false;
break;
case 65: //A
this.wasd.left = false;
break;
}
};
そして百悪のif文です.if (this.wasd.up) {
this.controller.translateZ(-this.translationSpeed * delta);
}
if (this.wasd.down) {
this.controller.translateZ(this.translationSpeed * delta);
}
if (this.wasd.right) {
this.controller.translateX(this.translationSpeed * delta);
}
if (this.wasd.left) {
this.controller.translateX(-this.translationSpeed * delta);
}
this.camera.position.addVectors(this.controller.position, this.headPos);
if (this.camera.position.y < -10) {
this.camera.position.y = -10;
}
早くあなたのHMDを取ってみてください.おわりに
私が『RePractise前端編:前端演進史』で言ったように、これは新しい「先端」のようです.