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

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

新規登録して質問してみよう
ただいま回答率
85.35%
if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

button

HTMLで用いる<button>タグです。

JavaScript

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

WebGL

WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。

Q&A

解決済

1回答

2958閲覧

JSを使用した、3Dモデルのアニメーション制御

ramen365

総合スコア1

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

button

HTMLで用いる<button>タグです。

JavaScript

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

WebGL

WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。

0グッド

0クリップ

投稿2021/09/17 05:11

前提・実現したいこと

3Dモデルの車に、ドア open / close のアニメーションを実装しています。
リンクからご確認いただけますでしょうか。

ボタンクリックして運転席側のドアをオープン後、助手席側のドアもオープンすると、運転席側が閉まります。
同時にオープン状態にするには、どんなコードにすれば良いでしょうか。
運転席側、助手席側を独立して動かしたいです。

現在は setTimeoutを使用して、アニメーションを制御しています。

プラットフォームは Google model-viewer になります。

コード初心者の為、皆様のお力をお貸しいただけますと幸いです。

発生している問題・エラーメッセージ

左右のドアが独立して動きません。

該当のソースコード

<body>`
<div class="wrapper">
<figure class="ar-img">
<model-viewer id="modelViewer" class="ar-model" src="porsche_v2.glb" animation-name="right_door" animation-name="left_door" camera-orbit="-50deg 85deg 50m" max-camera-orbit="auto 85deg 5m" min-camera-orbit="auto 0deg 5m" camera-target="auto auto auto" field-of-view="45deg" max-field-of-view="45deg" min-field-of-view="45deg" exposure="1.5" shadow-intensity="8.0" shadow-softness="0.2" environment-image="approaching_storm_1k.hdr" camera-controls>
<button class="aka1" id="Button1" animation-name="right_door" slot="hotspot1" onclick="Button1()" data-position="0.05631487185085804m 0.9982469014260928m -0.9695847388351034m" data-normal="-0.07570371106419371m 0.14147896900599324m -0.9870423747033915m" data-visibility-attribute="visible"> <script> document.getElementById("Button1").style.visibility ="visible"; function Button1(){ const Button1 = document.getElementById("Button1"); const Button2 = document.getElementById("Button2"); if(Button1.style.visibility=="visible"){ Button1.style.visibility ="hidden"; }else{ Button1.style.visibility ="visible"; } if(Button2.style.visibility=="hidden"){ Button2.style.visibility ="visible"; }else{ Button2.style.visibility ="hidden"; } } </script> <script> var aka1 = document.getElementById('Button1'); aka1.addEventListener('click', () => { self.setTimeout(() => { modelViewer.animationName = 'right_door'; modelViewer.play(); }, 0); self.setTimeout(() => { modelViewer.animationName = 'right_door'; modelViewer.pause(); }, 1000); })(); </script> </button> <button class="aka2" id="Button2" animation-name="right_door" slot="hotspot2" onclick="Button2()" data-position="0.05631487185085804m 0.9982469014260928m -0.9695847388351034m" data-normal="-0.07570371106419371m 0.14147896900599324m -0.9870423747033915m" data-visibility-attribute="visible"> <script> document.getElementById("Button2").style.visibility ="hidden"; function Button2(){ const Button2 = document.getElementById("Button2"); const Button1 = document.getElementById("Button1"); if(Button2.style.visibility=="visible"){ Button2.style.visibility ="hidden"; }else{ Button2.style.visibility ="visible"; } if(Button1.style.visibility=="hidden"){ Button1.style.visibility ="visible"; }else{ Button1.style.visibility ="hidden"; } } </script> <script> var timeout_id; var aka2 = document.getElementById('Button2'); aka2.addEventListener('click', () => { self.setTimeout(() => { modelViewer.animationName = 'right_door'; modelViewer.play(); }, 0); self.setTimeout(() => { modelViewer.animationName = 'right_door'; modelViewer.pause(); modelViewer.currentTime = 0; }, 1000); })(); </script> </button> <button class="ao1" id="Button3" animation-name="left_door" slot="hotspot6" onclick="Button3()" data-position="0.0726482461420125m 0.9864576348302633m 0.967550878481411m" data-normal="-0.01067212338320389m -0.8848665269268025m 0.4657223800795837m" data-visibility-attribute="visible"> <script> document.getElementById("Button3").style.visibility ="visible"; function Button3(){ const Button3 = document.getElementById("Button3"); const Button4 = document.getElementById("Button4"); if(Button3.style.visibility=="visible"){ Button3.style.visibility ="hidden"; }else{ Button3.style.visibility ="visible"; } if(Button4.style.visibility=="hidden"){ Button4.style.visibility ="visible"; }else{ Button4.style.visibility ="hidden"; } } </script> <script> var ao1 = document.getElementById('Button3'); ao1.addEventListener('click', (e) => { self.setTimeout(() => { modelViewer.animationName = 'left_door'; modelViewer.play(); }, 0); self.setTimeout(() => { modelViewer.animationName = 'left_door'; modelViewer.pause(); }, 1000); })(); </script> </button>   <button class="ao2" id="Button4" animation-name="left_door" slot="hotspot7" onclick="Button4()" data-position="0.0726482461420125m 0.9864576348302633m 0.967550878481411m" data-normal="-0.01067212338320389m -0.8848665269268025m 0.4657223800795837m" data-visibility-attribute="visible"> <script> document.getElementById("Button4").style.visibility ="hidden"; function Button4(){ const Button4 = document.getElementById("Button4"); const Button3 = document.getElementById("Button3"); if(Button4.style.visibility=="visible"){ Button4.style.visibility ="hidden"; }else{ Button4.style.visibility ="visible"; } if(Button3.style.visibility=="hidden"){ Button3.style.visibility ="visible"; }else{ Button3.style.visibility ="hidden"; } } </script> <script> var ao2 = document.getElementById('Button4'); ao2.addEventListener('click', (e) => { self.setTimeout(() => { modelViewer.animationName = 'left_door' modelViewer.play(); }, 0); self.setTimeout(() => { modelViewer.animationName = 'left_door' modelViewer.pause(); modelViewer.currentTime = 0; }, 1000); })(); </script> </button>

リンク内容

試したこと

イベントの停止等、試しましたが独立して動いてくれません。
色々と100回以上は試しております。。

補足情報(FW/ツールのバージョンなど)

プラットフォームは Google model-viewer になります。

アニメーションはオープンからクローズまで2秒のループです。

アニメーション書き出しは、
right_open / close   left_open / close まで1つのタイムラインです。

ボタンクリックは 赤 open / 青 close になります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

左右のドアが独立して動きません。

残念ながら現状 model-viewer では複数のアニメーションの同時再生には対応していないようです。

■ Autoplay All Animation
https://github.com/google/model-viewer/issues/1531

model-viewer's API only plays a single animation at a time, cross-fading between.
model-viewerのAPIは、一度に1つのアニメーションをクロスフェードで再生するだけです。

model-viewer の実装に使用されている Three.js というライブラリ自体は複数のアニメーション再生に対応しているので、どうしてもということであれば、そちらを使う感じでしょうか。

以下は Three.js を利用した glTF モデルのビューアになります。
https://gltf-viewer.donmccurdy.com/

右上のコントロールパネルより「playAll」ボタンをクリックすることで複数のアニメーションが同時に再生できることが確認できます。

■ glTF Viewer における複数アニメーションの同時再生の例
glTFモデルアニメーション表示例

投稿2021/09/17 13:47

cx20

総合スコア4648

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

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

ramen365

2021/09/18 00:23

ご回答いただきまして、ありがとうございます。 model-viewerでは現状無理なのですね。。。 頑張って、Three.jsを勉強します。 この度は、ありがとうございました!
cx20

2021/09/18 00:37

参考になるか分かりませんが、下記リポジトリにある Three.js のサンプルコードで複数のアニメーションの表示に対応しています。 https://github.com/cx20/gltf-test InterpolationTest の例を参照ください。
ramen365

2021/09/22 04:44

返答が遅くなりまして、申し訳ございません。 ご丁寧に、参考までお教えいただきまして感謝いたします。 ところで、cx20様は three.js はお詳しいでしょうか。 本番で使用したいデータがdraco圧縮したglbなのですが、色々なコードを試しても描写できません。。 よろしくお願いいたします。
cx20

2021/09/22 05:02

> データがdraco圧縮したglbなのですが、色々なコードを試しても描写できません。。 何でしょうね。。 念の為、モデルにエラーが無い事を確認お願いします。 以下のオンラインビューアにドラッグ&ドロップすると左下に検証結果「Validation report」が表示されます。 ■ glTF Viewer https://gltf-viewer.donmccurdy.com/ モデルに問題が無い場合、ブラウザのコンソールにエラーが出ていたりしませんか? 参考までに、以下は Draco 形式のモデルの表示例になります。 https://cx20.github.io/gltf-test/examples/threejs/index.html?category=sampleModels&model=Duck&scale=1&type=glTF-Draco
ramen365

2021/09/22 10:46

ありがとうございます! glTF Viewer で確認したところ、エラー表示はありませんでした。 また、コンソールのエラーも確認されませんでした。 three.js の仕組みが分からない上に、最初から最後まで記述されているコードが見当たらないので(draco部分の記述のみ)、色々な所から断片的なコードをつなぎ合わせた結果、表示できないと思います。。。
cx20

2021/09/22 13:31

> 最初から最後まで記述されているコード 試しに Draco 形式の glTF モデルを読み込むサンプルを用意してみました。こちらでどうでしょうか? https://jsfiddle.net/cx20/w5m1ep7n/ <参考> ■ Three.jsでモデルデータを読み込む https://ics.media/tutorial-three/model_basic/ ■ GLTFLoader – three.js docs https://threejs.org/docs/#examples/en/loaders/GLTFLoader ■ three.js webgl - glTF loader https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_gltf.html
ramen365

2021/09/22 14:08

cx20様 ありがとうございます!! 明日、すぐに確認してみます。 本当にいつもありがとうございます。
ramen365

2021/09/23 02:58

cx20様 ありがとうございます!!! 無事表示できました。! これから先、課題でありましたアニメーション制御を実装出来る様、努力いたします! この度は親身に相談に乗ってくださり、誠にありがとうございました。 これからも何卒よろしくお願い申し上げます。
cx20

2021/09/23 03:20

無事表示出来たようで何よりです。 Three.js の公式サイトに多くのサンプルが公開されていますので、やりたいことと近いサンプルを見つけてコードを確認することをお勧めします。 https://threejs.org/examples/ そういえば、Draco形式のglTFモデルの表示サンプルも公式サイトにありました(今、気が付きました)。参考情報まで。 https://threejs.org/examples/#webgl_animation_keyframes
cx20

2021/09/23 03:23

蛇足ですが、アニメーション制御についてはこちらが参考になるかも知れません。 ■ three.js 入門 (8) - アニメーションシステム https://note.com/npaka/n/n0311c7b0d681
ramen365

2021/09/23 04:21

ありがとうございます。 全て参考にいたします。 今後共、お力添えをいただけますと幸いです。 この度は本当にありがとうございました。
ramen365

2021/10/01 06:44

cx20様 いつもお世話になっております。 あれから色々と試行錯誤しまして、ここまでは出来る様になりました。 http://ramen36524.html.xdomain.jp/three.js-master/examples/webgl_animation_keyframes.html 左右同時にオープンすることは出来たのですが、挙動が変です。。。 原因がお分かりでしょうか。 又、コードはこの欄に記述してよろしいでしょうか。 よろしくお願いいたします。
cx20

2021/10/01 14:40

> 左右同時にオープンすることは出来たのですが、挙動が変です。。。 こちらでも試してみましたが、確かに同時再生すると挙動が怪しい気がしますね。。 https://gltf-viewer.donmccurdy.com/ 今時点ではモデルの問題かライブラリの問題か、ちょっと判断しかねます。。 こちらで表示しようとすると、エラーが出るので何かしらモデルにエラーを抱えているようにも思います。(それが正しくアニメーションされない原因かかどうかは分からないですが) https://sandbox.babylonjs.com/ ライブラリ側に問題を報告するにしても、モデルのエラーについて解消しないと調査してくれない気がします。。
ramen365

2021/10/03 01:58

cx20様 ありがとうございます! 一度モデルの仕組みを見直してみます。 又、ご報告いたしますので、何卒よろしくお願いします。
ramen365

2021/12/21 02:43

cx20様 ご無沙汰しております。 ドア開閉の問題はクリアできたのですが、初歩的な問題で躓いております。。 https://threejs.org/examples/#webgl_loader_gltf このコードを丸ごとコピーして、サーバにアップしたのですが、ヘルメットが真っ黒になってしまいます。 http://ramen365.starfree.jp/three.js-master1/examples/11262.html モデルを他に置き換えても、同じように真っ黒になるのです。。 原因が全く分からないので、困っております。 何卒、お知恵をお貸しいただけます様、よろしくお願い申し上げます。
cx20

2021/12/22 02:58 編集

あぁ、ようやくその事象を理解しました。ヘルメット自体が「真っ黒で何も表示されない」いうわけではなく、公式サイトの「サンプルと比べて暗い」ということですね。 たしかにその事象であれば、こちらでも確認できました。 原因はちょっと調べてみないと分かりません。
cx20

2021/12/22 03:01

別の話題である為、別質問でお願いできますか?
ramen365

2021/12/22 03:41

cx20様 ありがとうございます。 承知いたしました。 それでは新たに質問させていただきます。 よろしくお願い申し上げます。
cx20

2021/12/22 03:50

ちゃんと調べたわけでは無いですが、three.js のバージョンが違うのが関係しているかもしれません。最新版で再度試してもらえますか? 公式サイト)r135 自前のサイト)r125
ramen365

2021/12/22 09:28

cx20様 ありがとうございます! バージョン違いが影響していました。 最新で試したところ、きちんと描写しました。 ご対応いただきまして、感謝いたします。 これ以降は新たに質問させていただきますので、よろしくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問