鿍奍;: ãã®æ©è½ã¯éæ¨å¥¨ã«ãªãã¾ãããã¾ã 対å¿ãã¦ãããã©ã¦ã¶ã¼ãããããããã¾ãããããã§ã«é¢é£ããã¦ã§ãæ¨æºããåé¤ããã¦ããããåé¤ã®æç¶ãä¸ã§ããããäºææ§ã®ããã ãã«æ®ããã¦ããå¯è½æ§ãããã¾ãã使ç¨ãé¿ããã§ããã°æ¢åã®ã³ã¼ãã¯æ´æ°ãã¦ãã ããããã®ãã¼ã¸ã®ä¸é¨ã«ããäºææ§ä¸è¦§è¡¨ãè¦ã¦å¤æãã¦ãã ããããã®æ©è½ã¯çªç¶åä½ããªããªãå¯è½æ§ããããã¨ã«æ³¨æãã¦ãã ããã
å¤ãã® WebVR ãã¼ãã¦ã§ã¢ã¯ããããã»ããã¨ã²ã¼ã ããããã»ããã«ãªã£ã¦ãã¾ããWebVR ã¢ããªã«ããã¦ã¯ããããã»ããã¨ã²ã¼ã ãããã¯ã²ã¼ã ããã APIãéãã¦æ¥ç¶ããã¾ããä¸ã§ããã²ã¼ã ãããæ¡å¼µ API ã¯ãã²ã¼ã ãããã®ç¶æ (controller pose)ã触è¦ã¢ã¯ãã¥ã¨ã¼ã¿(haptic actuators)ãªã©ã®æ å ±ãåå¾ãã¾ãããã®è¨äºã§ã¯ããã®åºç¤ã¨ãªãé¨åã解説ãã¾ãã
ã¡ã¢: WebVR API 㯠WebXR API ã«ç½®ãæãããã¾ããã WebVR ã¯æ¨æºã¨ãã¦æ¹åããããã¨ã¯ãªããããå°æ°ã®ãã©ã¦ã¶ã¼ã§ããæ¢å®ã§å®è£ ã»æå¹åããããå°æ°ã®ç«¯æ«ãã対å¿ãã¦ãã¾ããã§ããã
WebVR APIWebVR API ã¯åææ®µéã§ã¯ããããéçºè ãã¦ã§ããã¼ã¹ã®ãã¼ãã£ã«ãªã¢ãªãã£ã¼çµé¨ãçã¿åºããã¨ã®ã§ããã¨ã¦ãè峿·±ãã¦ã§ãã®æ°ããæ©è½ã§ããã³ã³ãã¥ã¼ã¿ã¨ã¤ãªãã£ã¦ãã VR ãããã»ããï¼VR ãã£ã¹ãã¬ã¤ï¼ã¸ã®ã¢ã¯ã»ã¹ãä¸ãããã¨ã§ããã£ã¹ãã¬ã¤ãã¹ã¿ã¼ãããããã¹ãããããæä½ãã§ãã¾ããåãã®ãã¼ã¿ï¼ä¾ï¼æ¹åãä½ç½®ï¼ã¸ã¢ã¯ã»ã¹ãã¦å¾ããããã¼ã¿ã¯ãåã¢ãã¡ã¼ã·ã§ã³ã«ã¼ãã®ãã¬ã¼ã ãã¨ã«ãã£ã¹ãã¬ã¤ãã¢ãããã¼ããããããªã©ã«ä½¿ç¨ããã¾ãã
ãã®è¨äºãèªãåæã¨ãã¦ãWeb VR API ã®åºç¤ã«ã¤ãã¦ãã§ã«ç¥ã£ã¦ãããã¨ãæ³å®ãã¦ãã¾ãã â ããã¾ã WebVR API ã®ä½¿ç¨ã«ãèªãã§ããªãå ´åã«ã¯ãã¾ãã¯ãã¡ããèªãã§ã¿ã¾ãããããã®è¨äºã®ä¸ã§ã¯ããã©ã¦ã¶ã¼å´ããã¼ãã¦ã§ã¢ã®è¨å®ããµãã¼ãããããè¨å®ãè¦æ±ããããããã¨ã«ã¤ãã¦è©³ãã説æãã¦ãã¾ãã
ã²ã¼ã ããã APIã²ã¼ã ããã API ã¯ãããµãã¼ãããã API ã§ããã ããã使ç¨ãããã¨ã§ PC ã«ã¤ãªãã£ã¦ããã²ã¼ã ããããã²ã¼ã ãããã«éçºè ãã¢ã¯ã»ã¹ãããã¨ãã§ããããã«ãªãã¾ããã¾ããã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ãã²ã¼ã ããããã²ã¼ã ããããéãã¦æä½ãããã¨ãã§ããããã«ãªãã¾ããåºæ¬ã¨ãã¦ã²ã¼ã ããã API ã¯ãã²ã¼ã ããããªãã¸ã§ã¯ãã¨ãã¦ã¤ãªãã£ã¦ããã²ã¼ã ãããã«å¯¾ãã¦ã¢ã¯ã»ã¹ã®è¨±å¯ãä¸ãã¾ããããã¦ã©ã®ãã¿ã³ãæ¼ããã¦ãããã軸ãã©ã®æ¹åã«åãã¦ããããªã©ã®æ å ±ãåå¾ããããè¦æ±ãã¾ãã
ã²ã¼ã ããã API ã®åºæ¬çãªä½¿ãæ¹ã«ã¤ãã¦ã¯ãã²ã¼ã ããã API ã®ä½¿ç¨ãã²ã¼ã ããã API ã使ç¨ããå¶å¾¡ã®å®è£ ã®ä¸ã§è©³ããç¥ããã¨ãã§ãã¾ãã
ããããªããããã®è¨äºã§ã¯ä¸»ã«ãä½ç½®ãæ¹åã触è¦ã¢ã¯ãã¥ã¨ã¼ã¿ã¼ï¼ãã¤ãã¬ã¼ã·ã§ã³ï¼ãªã©ã®é«åº¦ãªã²ã¼ã ãããæ å ±ã¸ã®ã¢ã¯ã»ã¹ã®ãããªãã²ã¼ã ãããæ¡å¼µ API ã§ä¸ããããããã¤ãã®æ°ããç¹å¾´ã«æ³¨ç®ãã¾ãããã® API ã¯ã¨ã¦ãæ°ãããFirefox 55+ Beta ã Firefox Nightly ã®ãã©ã¦ã¶ã¼ã§ã®ã¿ããã©ã«ãã§ WebVR API ããµãã¼ãããã¦ãã¾ãã
ã²ã¼ã ãããã®ç¨®é¡VR ãã¼ãã¦ã§ã¢ã«ä»éããã²ã¼ã ãããã«ã¯ãï¼ã¤ã®ç¨®é¡ãããã¾ãã
ããã§ã¯ããã¤ãã®ã³ã¼ããç´¹ä»ãã¾ããã¾ããGamepad API ã使ç¨ã㦠VR ã²ã¼ã ãããã¸ã®åºæ¬çãªã¢ã¯ã»ã¹æ¹æ³ãè¦ã¦ããã¾ããããããã¤ãã®ããããªãã¥ã¢ã³ã¹ãå¿ã«çãã¦ããã¾ããããããã¯å¾ãã調ã¹ã価å¤ããããã®ã§ãã
ã·ã³ãã«ãªä¾ãç´¹ä»ãã¾ãã-vr-controller-basic-info ã®ã½ã¼ã¹ã³ã¼ã (see it running live here also) ã御覧ãã ããããã®ä¾ã¯ VR ãã£ã¹ãã¬ã¤ãã³ã³ãã¥ã¼ã¿ã¼ã¨æ¥ç¶ããã²ã¼ã ã²ã¼ã ãããã¸æ å ±ãåºåããã·ã³ãã«ãªãã®ã§ãã
ãã£ã¹ãã¬ã¤ã®æ å ±ãå徿åã®ã³ã¼ãã§ãã
let initialRun = true;
if (navigator.getVRDisplays && navigator.getGamepads) {
info.textContent = "WebVR API and Gamepad API supported.";
reportDisplays();
} else {
info.textContent =
"WebVR API and/or Gamepad API not supported by this browser.";
}
ããã§ã¯ãinitialRun
ãã¨ãããã©ããã³ã°ã®å¤æ°ã使ãã¾ããããã¯ãããã®ãã¼ã¸ãåãã¦ãã¼ãããããã¨ã示ãã¾ãããã®ç¹ã«ã¤ãã¦ã¯ããã¨ã§è©³ããè¿°ã¹ã¾ããæ¬¡ã«ãNavigator.getVRDisplays()
㨠Navigator.getGamepads()
ã¡ã½ãããããããªããããã§ãã¯ãã¦ãWebVR 㨠Gamepad APIs ããµãã¼ãããã¦ãããã©ãããæ¤ç¥ãã¾ããããããµãã¼ãããã¦ããã°ãæ¤ç¥ããããã»ã¹ã OFF ã«ããããã«ãã«ã¹ã¿ã æ©è½ã§ãã reportDisplays()
ãå®è¡ãã¾ãã reportDisplays()
ã¯ã以ä¸ã®ãããªæ§æã«ãªã£ã¦ãã¾ãã
function reportDisplays() {
navigator.getVRDisplays().then((displays) => {
console.log(`${displays.length} displays`);
displays.forEach((display, i) => {
const cap = display.capabilities;
// cap is a VRDisplayCapabilities object
const listItem = document.createElement("li");
listItem.innerHTML =
`<strong>Display ${i + 1}</strong><br>` +
`VR Display ID: ${display.displayId}<br>` +
`VR Display Name: ${display.displayName}<br>` +
`Display can present content: ${cap.canPresent}<br>` +
`Display is separate from the computer's main display: ${cap.hasExternalDisplay}<br>` +
`Display can return position info: ${cap.hasPosition}<br>` +
`Display can return orientation info: ${cap.hasOrientation}<br>` +
`Display max layers: ${cap.maxLayers}`;
list.appendChild(listItem);
});
setTimeout(reportGamepads, 1000);
// For VR, controllers will only be active after their corresponding headset is active
});
}
ãã®é¢æ°ã¯æåã«ãããã¹ãã¼ã¹ã® Navigator.getVRDisplays()
ã¡ã½ããã使ç¨ããæ¥ç¶ããããã£ã¹ãã¬ã¤ã表ã VRDisplay
ãªãã¸ã§ã¯ããå«ãé
åã使ç¨ãã¦è§£æ±ºãã¾ããæ¬¡ã«ãåãã£ã¹ãã¬ã¤ã® VRDisplay.displayId
㨠VRDisplay.displayName
å¤ãããã³ãã®ãã£ã¹ãã¬ã¤ã«é¢é£ä»ãããã VRCapabilities
ãªãã¸ã§ã¯ãã«æ ¼ç´ããã¦ããå¤ãã®æç¨ãªå¤ã表示ããã¾ãããããã®ãã¡æãæçãªã®ã¯ hasOrientation
㨠hasPosition
ã§ãããã«ããæ©å¨ãåãã¨ä½ç½®ã®ãã¼ã¿ãè¿ããã¨ãã§ãããã©ãããæ¤åºããããã«å¿ãã¦ã¢ããªãè¨å®ãããã¨ãã§ãã¾ãã
ãã®é¢æ°ã«å«ã¾ããæå¾ã®è¡ã¯ setTimeout()
å¼ã³åºãã§ã 1 ç§å¾ã« reportGamepads()
颿°ãå®è¡ãã¾ãããªããã®ãããªãã¨ãå¿
è¦ãªã®ã§ããããï¼ã¾ã第ä¸ã«ã VR ã³ã³ããã¼ã©ã¼ã¯é¢é£ãã VR ãããã»ãããã¢ã¯ãã£ãã«ãªã£ã¦åãã¦æºåãæ´ãã¾ãããã®ãããgetVRDisplays()
ãå¼ã³åºããã¦ãã£ã¹ãã¬ã¤æ
å ±ãè¿ããå¾ã«ããã®é¢æ°ãå¼ã³åºãå¿
è¦ãããã¾ãã 2 ã¤ç®ã¨ãã¦ãã²ã¼ã ããã API 㯠WebVR API ããããã£ã¨å¤ãããããã¹ãã¼ã¹ã§ã¯ããã¾ãããå¾ã»ã©èª¬æãã¾ãããgetGamepads()
ã¡ã½ããã¯åæåã§ãGamepad
ãªãã¸ã§ã¯ããããã«è¿ãã ãã§ã - ã³ã³ããã¼ã©ã¼ãæ
å ±ãå ±åããæºåãã§ããã¾ã§å¾
ã¤ãã¨ã¯ããã¾ãããå°ãå¾
ããªãã¨ãè¿ãããæ
å ±ã¯æ£ç¢ºã§ã¯ãªãããããã¾ããï¼å°ãªãã¨ããæã
ã®ãã¹ãã§ã¯ããã§ããï¼ã
reportGamepads()
颿°ã¯ããã®ãããªæ§æã«ãªã£ã¦ãã¾ãã
function reportGamepads() {
const gamepads = navigator.getGamepads();
console.log(`${gamepads.length} controllers`);
for (const gp of gamepads) {
const listItem = document.createElement("li");
listItem.classList = "gamepad";
listItem.innerHTML =
`<strong>Gamepad ${gp.index}</strong> (${gp.id})<br>` +
`Associated with VR Display ID: ${gp.displayId}<br>` +
`Gamepad associated with which hand: ${gp.hand}<br>` +
`Available haptic actuators: ${gp.hapticActuators.length}<br>` +
`Gamepad can return position info: ${gp.pose.hasPosition}<br>` +
`Gamepad can return orientation info: ${gp.pose.hasOrientation}`;
list.appendChild(listItem);
}
initialRun = false;
}
ãã㯠reportDisplays()
ã¨åãããã«åä½ãã¾ãããããã¹ã§ãªã getGamepads()
ã¡ã½ããã使ç¨ã㦠Gamepad
ãªãã¸ã§ã¯ãã®é
åãåå¾ããããããã®ãªãã¸ã§ã¯ãã循ç°ãã¦æ
å ±ã表示ãã¦ãã¾ãã
Gamepad.displayId
ããããã£ã¯ãã³ã³ããã¼ã©ã¼ãé¢é£ä»ãããã¦ãããããã»ããã® displayId
ã¨åããªã®ã§ãã³ã³ããã¼ã©ã¼ã¨ãããã»ããã®æ
å ±ãçµã³ä»ãã¦ä½¿ç¨ããã®ã«æçãªæ
å ±ã§ããGamepad.index
ããããã£ã¯ãæ¥ç¶ãããåã³ã³ããã¼ã©ã¼ãèå¥ããããã®åºæã®æ°å¤ã¤ã³ããã¯ã¹ã§ããGamepad.hand
ã¯ãã³ã³ããã¼ã©ã¼ãã©ã¡ãã®æã§æ¡ããããã¨ãæ³å®ãã¦ããããè¿ãããããã£ã§ããGamepad.hapticActuators
ã¯ãã³ã³ããã¼ã©ã¼ã§å©ç¨ã§ãããããã£ãã¯ã¢ã¯ãã¥ã¨ã¼ã¿ã®é
åãè¿ãã¾ããããã§ã¯ããããããå©ç¨ã§ããæ°ã確èªããããã«ããã®é·ããè¿ãã¦ãã¾ããGamepadPose.hasPosition
㨠GamepadPose.hasOrientation
ãè¿ãããã«ãã¦ãã¾ããããã¯ãã£ã¹ãã¬ã¤ã®å ´åã¨åãããã«åä½ãã¾ãããã²ã¼ã ãããã®å ´åããããã®å¤ã¯ capabilities ãªãã¸ã§ã¯ãã§ã¯ãªã pose ãªãã¸ã§ã¯ãã§å©ç¨ã§ãã¾ããã³ã³ããã¼ã©ã¼æ
å ±ãå«ããªã¹ãé
ç®ã«ã¯ããããã gamepad
ã¨ããã¯ã©ã¹åãä»ãã¦ãããã¨ã«æ³¨æãã¦ãã ããããããä½ã®ããã«ããã®ãã¯ãå¾ã§èª¬æãã¾ãã
æå¾ã«ãinitialRun
夿°ã false
ã«è¨å®ãã¾ããããã§åæå®è¡ã¯çµããã§ãã
ãã®ç« ã®ä»ä¸ãã¨ãã¦ãã²ã¼ã ãããã«é¢é£ããã¤ãã³ããè¦ã¦ããã¾ãã1 人ã¾ã㯠2 人ã§ã - gamepadconnected
㨠gamepaddisconnected
- ããã¦ããããè¡ããã¨ã¯ããªãæç½ã§ãã
ãã®ä¾ã®çµããã«ã¯ãã¾ã removeGamepads()
颿°ãè¨è¼ãã¦ãã¾ãã
function removeGamepads() {
const gpLi = document.querySelectorAll(".gamepad");
for (let i = 0; i < gpLi.length; i++) {
list.removeChild(gpLi[i]);
}
reportGamepads();
}
ãã®é¢æ°ã¯ãã¯ã©ã¹åã gamepad
ã§ãããã¹ã¦ã®ãªã¹ãé
ç®ã¸ã®åç
§ãåå¾ããDOM ããåé¤ãã¾ãããã®å¾ãreportGamepads()
ãåå®è¡ãã¦ãæ¥ç¶ããã¦ããã³ã³ããã¼ã©ã®ãªã¹ããæ´æ°ãã¦ãã¾ãã
removeGamepads()
ã¯ãã²ã¼ã ããããæ¥ç¶ã¾ãã¯åæããããã³ã«ã以ä¸ã®ã¤ãã³ããã³ãã©ã¼ã§å®è¡ããã¾ãã
window.addEventListener("gamepadconnected", (e) => {
info.textContent = `Gamepad ${e.gamepad.index} connected.`;
if (!initialRun) {
setTimeout(removeGamepads, 1000);
}
});
window.addEventListener("gamepaddisconnected", (e) => {
info.textContent = `Gamepad ${e.gamepad.index} disconnected.`;
setTimeout(removeGamepads, 1000);
});
ããã§ã¯ãã¹ã¯ãªããä¸é¨ã®åæåã³ã¼ãã§è¡ã£ãããã« setTimeout()
ãææãã¦ãããåã±ã¼ã¹ã§ reportGamepads()
ãå¼ã³åºãããã¨ãã«ã²ã¼ã ããããæ
å ±ãå ±åããæºåãã§ãã¦ãããã¨ã確èªãããã¨ãã§ãã¾ãã
ããããããä¸ã¤ã¡ã¢ãããã¾ãã gamepadconnected
ãã³ãã©ã¼ã®å
é¨ã§ã¯ã initialRun
ã false
ã®ã¨ãã ãã¿ã¤ã ã¢ã¦ããå®è¡ããããã¨ããããã¨æãã¾ããããã¯ãææ¸å
ã®æåã®ãã¼ãæã«ã²ã¼ã ããããæ¥ç¶ããã¦ããå ´åãã²ã¼ã ããããã¨ã« gamepadconnected
ãçºè¡ãããããã removeGamepads()
/reportGamepads()
ãè¤æ°åå®è¡ããããã¨ã«ãªãããã§ãããã®ãããremoveGamepads()
㯠gamepadconnected
ãã³ãã©ã¼ã®ä¸ã§ãæåã®å®è¡æã§ã¯ãªããå®è¡å¾ã«å®è¡ããããã«ãããã§ãããã®ããã« initialRun
ãããã¾ãã
å®éã® WebVR ã®ãã¢ã§ä½¿ç¨ããã Gamepad API ãè¦ã¦ã¿ã¾ãããããã®ãã¢ã¯raw-webgl-controller-example (ã©ã¤ããã¢ã覧ãã ãã).ã§è¦ããã¨ãã§ãã¾ãã
ç§éã®raw-webgl-example (詳ãã㯠Using the WebVR API ã御覧ãã ããã)ã¨åãæ¹æ³ã§ããã®ãã¢ã«ããã¦ãå転ãã 3D ç«æ¹ä½ãã¬ã³ããªã³ã°ãã¦ãã¾ããã¾ããããã VR ãã£ã¹ãã¬ã¤ã¸æå½±ãããã¨ãã§ãã¾ããå¯ä¸ã®éãã¨ãã¦ã¯ãVR ãã£ã¹ãã¬ã¤ã¸æå½±ã¢ã¼ãã§ã¯ãVR ã²ã¼ã ãããã使ã£ã¦ç«æ¹ä½ãåãããã¨ãã§ãã¾ããï¼ãªãªã¸ãã«ã®ãã¢åç»ã§ã¯ãVR ãããã»ãããåãããã¨ã§ãç«æ¹ä½ãåãããã¨ãã§ãããï¼
以ä¸ã«ããã®ãã¼ã¸ã§ã³ã§ã®ã³ã¼ãã®éãããã詳ããç´¹ä»ãã¾ããwebgl-demo.js ã御覧ãã ããã
ã²ã¼ã ããããã¼ã¿ã¸ã®ã¢ã¯ã»ã¹drawVRScene()
颿°ã«ã¤ãã¦ã®ã³ã¼ãã®ä¸é¨ã§ãã
const gamepads = navigator.getGamepads();
const gp = gamepads[0];
if (gp) {
const gpPose = gp.pose;
const curPos = gpPose.position;
const curOrient = gpPose.orientation;
if (poseStatsDisplayed) {
displayPoseStats(gpPose);
}
}
Navigator.getGamepads
ãå©ç¨ãã¦ãã²ã¼ã ããããæ¥ç¶ããã¾ãããã¾ã gp
夿°ã®ä¸ã«æåã«èªèããã²ã¼ã ããããä¿åãã¾ãã ãã¢ã§ã¯ãã²ã¼ã ããããä¸ã¤ãã使ç¨ããªãã®ã§ããã®ä»ã®ã²ã¼ã ãããã¯ç¡è¦ãã¾ãã
次ã«è¡ããã¨ã¯ãgpPose ã«æ ¼ç´ããã¦ããã³ã³ããã¼ã©ã¼ã® GamepadPose
ãªãã¸ã§ã¯ããåå¾ã (Gamepad.pose
ãã¯ã¨ãªã¼ãã¦)ãã¾ããã®ãã¬ã¼ã ã®ç¾å¨ã®ã²ã¼ã ãããã®ä½ç½®ã¨æ¹åã夿°ã«æ ¼ç´ãã¦ãå¾ã§å®¹æã«ã¢ã¯ã»ã¹ã§ããããã«ãããã¨ã§ããã¾ãã displayPoseStats()
颿°ã使ç¨ãã¦ããã®ãã¬ã¼ã ã®ãã¹ãçµ±è¨æ
å ±ã DOM ã«è¡¨ç¤ºãã¾ãããã®å¦çã¯ãã¹ã¦ gp
ãå®éã«å¤ãä¿æãã¦ããå ´åï¼ã²ã¼ã ããããæ¥ç¶ããã¦ããå ´åï¼ã«ã®ã¿è¡ãããã²ã¼ã ããããæ¥ç¶ãã¦ããªãå ´åã«ãã¢ãã¨ã©ã¼ã«ãªããªãããã«ãã¦ãã¾ãã
ã³ã¼ãã®å°ãå¾ã«ããã®ãããã¯ãè¦ã¤ãããã¨ãã§ãã¾ãã
if (gp && gpPose.hasPosition) {
mvTranslate([
0.0 + curPos[0] * 15 - curOrient[1] * 15,
0.0 + curPos[1] * 15 + curOrient[0] * 15,
-15.0 + curPos[2] * 25,
]);
} else if (gp) {
mvTranslate([0.0 + curOrient[1] * 15, 0.0 + curOrient[0] * 15, -15.0]);
} else {
mvTranslate([0.0, 0.0, -15.0]);
}
ããã§ã¯ãæ¥ç¶ãããã³ã³ããã¼ã©ã¼ããåãåã£ã position
㨠orientation
ãã¼ã¿ã«å¾ã£ã¦ãç»é¢ä¸ã®Cubeã®ä½ç½®ã夿´ãã¾ãããããã®å¤(curPos
㨠curOrient
ã«æ ¼ç´ããã¾ã)㯠XãYãZ ã®å¤ãå«ã Float32Array
s ã§ã (ããã§ã¯ X ã§ãã [0] 㨠Y ã§ãã [1] ã ã使ç¨ãã¦ãã¾ã)ã
夿° gp
ã®ä¸ã« Gamepad
ãªãã¸ã§ã¯ãããããä½ç½®å¤ãè¿ããã¨ãã§ããå ´å (gpPose.hasPosition
) ã¯ã6DoF ã³ã³ããã¼ã©ã¼ã示ãã¦ããã®ã§ãä½ç½®ã¨æ¹åã®å¤ã使ã£ã¦ãã¥ã¼ãã®ä½ç½®ã夿´ãã¾ ããåè
ã®ã¿ãçã®å ´åã3DoF ã³ã³ããã¼ã©ã¼ã示ããæ¹åå¤ã®ã¿ã使ç¨ãã¦ãã¥ã¼ãã®ä½ç½®ã夿´ãã¾ããã²ã¼ã ããããæ¥ç¶ããã¦ããªãå ´åããã¥ã¼ãã®ä½ç½®ã¯ãã¹ã¦å¤æ´ããã¾ããã
displayPoseStats()
颿°ã§ã¯ãGamepadPose
ãªãã¸ã§ã¯ãã®ãã¡ã®è¡¨ç¤ºããããã¹ã¦ã®æ
å ±ãåå¾ãããã¨ãã§ãã¾ããããã¦ããã®ãããªãã¼ã¿ã表示ããããã®ãã¢ã®ä¸ã«åå¨ãã UI ããã«ã«è¡¨ç¤ºãã¾ãã
function displayPoseStats(pose) {
const pos = pose.position;
const formatCoords = ([x, y, z]) =>
`x ${x.toFixed(3)}, y ${y.toFixed(3)}, z ${z.toFixed(3)}`;
posStats.textContent = pose.hasPosition
? `Position: ${formatCoords(pose.position)}`
: "Position not reported";
orientStats.textContent = pose.hasOrientation
? `Orientation: ${formatCoords(pose.orientation)}`
: "Orientation not reported";
linVelStats.textContent = `Linear velocity: ${formatCoords(
pose.linearVelocity,
)}`;
angVelStats.textContent = `Angular velocity: ${formatCoords(
pose.angularVelocity,
)}`;
linAccStats.textContent = pose.linearAcceleration
? `Linear acceleration: ${formatCoords(pose.linearAcceleration)}`
: "Linear acceleration not reported";
angAccStats.textContent = pose.angularAcceleration
? `Angular acceleration: ${formatCoords(pose.angularAcceleration)}`
: "Angular acceleration not reported";
}
ã¾ã¨ã
ãã®è¨äºã¯ãWebVR ã¢ããªã®ä¸ã§ VR ã²ã¼ã ãããã使ãããã«ã¯ãã©ã®ããã« Gamepad Extensions ãç¨ããã°ããã®ãã¨ããã¨ã¦ãåºæ¬çãªæ¦å¿µã解説ãããã®ã§ããå®éã® WebVR ã¢ããªã®ä¸ã§ã¯ãVR ã²ã¼ã ãããã®ãã¿ã³ã«ç´ä»ããããã²ã¼ã ãããã«ãããããããããè¤éãªã³ã³ããã¼ã«ã·ã¹ãã ããããããã¨ã«ãªãã§ãããã ããã¦ããã£ã¹ãã¬ã¤ã¨ã²ã¼ã ãããã®ä¸¡æ¹ã®æ å ±ï¼ä½ç½®ãæ¹åï¼ãåæçã«ãã£ã¹ãã¬ã¤ã¸ãã£ã¼ãããã¯ããã¨ããè¤éãªå¦çãè¡ããã¨ã«ãªãã¾ãããããããã®è¨äºã§ããããã£ãã®ã¯ãGamepad Extensions ã®ä¸ã®ç´ç²ãª Gamepad Extensions é¨åãåãåããã¨ãããã¨ã§ãã
é¢é£é ç®RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4