質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Monaca

「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

Q&A

解決済

1回答

1351閲覧

three.js の deviceorientation で物体を回転させたい

comeon

総合スコア9

Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Monaca

「Monaca」はiOS、Android、Windows向けのアプリ開発に対応した、Cordovaベースのモバイルアプリ開発プラットフォームです。HTML5、JavaScriptといったWeb標準技術を用いてモバイルアプリ開発を行うことができます。

0グッド

0クリップ

投稿2018/09/17 07:05

3Dのコンパスを作りたいと思っています。
(例:https://github.com/richtr/Marine-Compass)

まずthree.jsでメッシュのボックスを作って、OrbitControlsでマウスを操作
するとボックスの中心を固定してボックスが回転するような表示になります。
(例:https://ics-creative.github.io/tutorial-three/samples/camera_orbitcontrols_basic.html)
次にdeviceorientationで操作すると、ボックス位置は固定されたまま
カメラが回転するような表示になってしまい、カメラ(スマホ)が横を向くと
ボックスは画面から消えてしまいます。

Orbitcontrolsで表示されるような、ボックスの中心を固定したまま
deviceorientationでボックスを回転させるような操作方法を教えて
頂けませんか。Orbitcontrolsのオプションなどでdeviceorientation
のデータを取り込む方法や、またはdeviceorientationでボックス中心を
固定したままカメラの回転ではなくボックスを回転させるような方法はありませんか。

なおmonacaで開発中です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

スマホデバイスの角度を視点ではなく中の物体に与える、という感じでよいでしょうか。

↓サンプルはこんな感じです。
http://adrs2002.com/mrb/sample/deviceOrienTest.html

//↓を、初期化&1回でも tick が走った「後」に、一度だけ呼んでください controls = new THREE.DeviceOrientationControls(camera); camera.updateProjectionMatrix(); //Models の中に、映す&回転させたい物体が登録されています //毎フレームループはこんな感じ function tick() { //一度、コントローラーの更新をかけて、値を反映させる if(controls) { controls.update(); //更新後、カメラ角度をモデルの回転に与える(inverse = 逆にしています。 inverseナシもお試しください) Models[0].quaternion.copy(camera.quaternion.inverse()); //LookAtでモデルを強制的に見る角度(初期位置)に変える camera.lookAt(0, 1, 0); //重要!matrixAutoUpdateを切り、scene.update で更新されないようにする! camera.matrixAutoUpdate = false; } renderer.render(scene, camera); requestAnimationFrame(tick); }

three.js の中で、スマホの回転をどう扱っているかは、 DeviceOrientationControls のソースを見るのがよいでしょう
https://gist.github.com/kopiro/86aac4eb19ac29ae62c950ad2106a10e

投稿2018/09/20 14:33

adrs2002

総合スコア203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

comeon

2018/09/21 08:48

ご回答ありがとうございました。 ご提示いただいたサンプルはまさしく実現したいものです。 アドバイス及びサンプルのソースを参考にいろいろやっておりますが、どうもうまくいきません。 Githubのソースは難しくてわかりませんでした。 以下コードを添付しますので、さらにアド梅雨を
comeon

2018/09/21 08:51

(すみません、途中で送信してしまいました) ご回答ありがとうございました。 ご提示いただいたサンプルはまさしく実現したいものです。 アドバイス及びサンプルのソースを参考にいろいろやっておりますが、どうもうまくいきません。 Githubのソースは難しくてわかりませんでした。 以下コードを添付しますので、さらにアドバイスを頂けないでしょうか。 <script> (function() { 'use strict'; var scene; var box; var light; var ambient; var camera; var gridHelper; var renderer; var controls; var width = window.innerWidth; var height = window.innerHeight; //scene scene = new THREE.Scene(); //box box = new THREE.Mesh( new THREE.BoxGeometry(40, 40, 40), new THREE.MeshLambertMaterial({ color: 0xff0000 }) ); box.position.set(0, 0, 0); scene.add(box); //light light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 100, 30); scene.add(light); ambient = new THREE.AmbientLight(0x404040); scene.add(ambient); //camera camera = new THREE.PerspectiveCamera(100, width / height, 1, 5000); camera.position.set(0, 100, 300); camera.lookAt(scene.position); //helper gridHelper = new THREE.GridHelper(500, 50, 0xff0000); scene.add(gridHelper); //controls // controls = new THREE.OrbitControls(camera); controls = new THREE.DeviceOrientationControls(camera); camera.updateProjectionMatrix(); //renderer renderer = new THREE.WebGLRenderer({ antialias: true}); renderer.setSize(width, height); renderer.setClearColor(0x000000); renderer.setPixelRatio(window.devicePixelRatio); document.getElementById('stage').appendChild(renderer.domElement); // function render() { // requestAnimationFrame(render); // controls.update(); // renderer.render(scene, camera); // } // render(); function tick() { requestAnimationFrame(tick); //一度、コントローラーの更新をかけて、値を反映させる if(controls) { controls.update(); //更新後、カメラ角度をモデルの回転に与える(inverse = 逆にしています。 inverseナシもお試しください) box.quaternion.copy(camera.quaternion.inverse()); //LookAtでモデルを強制的に見る角度(初期位置)に変える camera.lookAt(0, 1, 0); //重要!matrixAutoUpdateを切り、scene.update で更新されないようにする! camera.matrixAutoUpdate = false; } render(); } function render() { renderer.render(scene, camera); } })(); </script>
adrs2002

2018/09/21 09:48

ご提示いただいたソースが全て・・・であるとすれば、上記処理だと、一度も `tick();` が呼ばれていないと思います。どこかで一回呼ぶと動いたりしませんでしょうか。 画面に緑の■が表示されているー>tick()が呼ばれているので、カメラとスマホの連動ができていない 画面に緑の■が表示されてないー>tick()が呼ばれていないので、呼ぶ処理を挟めば、かわるかも
comeon

2018/09/22 01:39

アドバイスありがとうございます。scriptの最後にtick();を入れてみましたが変わりません。 現状で背景の黒のみでボックスとgridhelperは表示されていない状況です。 consoleを見るとエラーは出ていないのですが The deviceorientation events are blocked by feature policy. See https://github.com/WICG/feature-policy/blob/master/features.md#sensor-features とあります。リンク先を読みましたがやはり理解できません。これが何か関係している可能性はありませんか。
comeon

2018/09/22 02:31

追加で、いままでmonacaブラウザで動作確認していましたが、ふと思いついてサーバーにアップロードして 確認したところ、状況は同じ(背景の黒のみでボックスとgridhelperは表示されていない)でしたが The deviceorientation events are blocked by feature policy. の表示は消えました。tick();もscriptの 最後に入れています。
adrs2002

2018/09/22 06:29

function tick() を、こう書き換えてみてください ( controls の宣言を移動させた )。自分も一度ハマった現象な気がします(camera を一度 render で更新させてからでないと、うまくいかない) ``` function tick() { requestAnimationFrame(tick); //一度、コントローラーの更新をかけて、値を反映させる if(controls) { controls.update(); //更新後、カメラ角度をモデルの回転に与える(inverse = 逆にしています。 inverseナシもお試しください) box.quaternion.copy(camera.quaternion.inverse()); //LookAtでモデルを強制的に見る角度(初期位置)に変える camera.lookAt(0, 1, 0); //重要!matrixAutoUpdateを切り、scene.update で更新されないようにする! camera.matrixAutoUpdate = false; render(); } else { render(); controls = new THREE.DeviceOrientationControls(camera); camera.updateProjectionMatrix(); } } ```
comeon

2018/09/23 02:37

アドバイスありがとうございました。早速修正してみたのですがやはり状況はかわりません。 現在の状況をサーバーにアップロードしました。 http://comeon897.html.xdomain.jp/deviceorientation/ お手数をおかけして申し訳ありませんが、ご確認の上アドバイスいただけないでしょうか。
adrs2002

2018/09/23 15:24

サイト見てみました。まず気になったのは、 ・ tick() が一度も呼ばれていません。これだと、ループに入らないので真っ黒で何も起きないままです。 ・ tick() の中で使用している render(); がコメントアウトされているので、戻しました。 ・ 69行目と70行目をコメントアウトしました。 んで、↓のようになりました。 http://adrs2002.com/mrb/sample/tes.html
comeon

2018/09/24 07:17

ありがとうございます。ご紹介いただいたリンクはまさに完成形です。 renderを一度行ってから同じ処理をtickでループすることを理解し、アドバイスをもとに修正を行いました。ところがうまく動作しません。 http://comeon897.html.xdomain.jp/deviceorientation/index2.html コードにどこか問題があるのかもしれないと思い、ご紹介いただいたリンクのソースをそのままコピーし、アップロードしましたがなぜかこちらも動作しません。 http://comeon897.html.xdomain.jp/deviceorientation/index.html その他ディレクトリ構造やフォルダ名を修正したり、chrome以外のブラウザでも試しましたがいずれ もうまくいきません。 いったい何故なのでしょうか....サーバーに問題があるのでしょうか。
adrs2002

2018/09/24 08:01

うーん、自分の書いた方のソースを冷静に見直したら、「なんでこれでちゃんと動くんだろう」と不思議に思ってしまいました。すみません。 原因は、「ループに render() が2回登録されている」ことになります。今のソースの 110行目と 114行目の render() を renderer.render(scene, camera); に差し替えてみてください( render() メソッドが不要になります。最初にコメントアウトされていたのが正解でした・・・)。
comeon

2018/09/25 03:23

すみません、やっぱり動きません.... 110行目と114行目を以下のように修正しました。 http://comeon897.html.xdomain.jp/deviceorientation/index2.html そのほかいろいろいじってみましたが、どうしてもうまくいきません。 何度も申し訳ありませんが、どうか教えてください。
adrs2002

2018/09/25 06:46

いろいろ情報をひっかきまわしてしまい、申し訳ありません。 なぜ自分のほうが動き、comeonさんのが動かなかったというと、 Three.jsのバージョンが、違っていました・・。 試しにcomeonさんのファイルを、そのまま自分の持っているフォルダ(Three.jsのバージョン:86)にいれたところ、問題なく動作しました。 自分も最新版で動かすことを調査してみますが、とりあえずご報告です・・。
adrs2002

2018/09/25 06:54

Ver96(最新)でも、108行目をコメントアウトしたら動きました。 …バージョンはきちんと合わせないとダメですね。失礼いたしました…。
comeon

2018/09/26 01:35

う、動きました.... ありがとうございます! Three.jsのバージョンが違うとコードも変わるんですね..... 本当にありがとうございます。最後まで辛抱強くご指導いただき、ありがとうございます。 なぜこの一行で動作が変わってしまうのか、これからいじりながらじっくり考えます。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問