Qt勉強会の成果 Qt3Dを使ってみた
Qt3D StudioとQt3D
以前Qt3D Studioを使って3Dの表現を試したことはあったのですが、今日はQtCreatorでQt3Dを使ってみました。
Qt3D Studioはタイムラインを使って3Dモデルを動かすシーケンサーのような印象を持ちましたが、Qt3Dはもっとプラグラマがゴリゴリ実装する感じ。
サッと3Dを使った表現を作るにはQt3D Studioは向いてそうですが、1個のアプリとして色々やるにはQMLでQt3Dを使ったほうが良いのかなと今は思ってます。
実装したプロジェクトはこちら github.com
できたもの
自分ではモデリングできないので、フリー素材を利用させていただきました。 雰囲気をだすために建物を置いて、道路を車が直進していくというものです。
ただ真っ直ぐ走るだけでは面白くないので、マウスクリックすると車がジャンプするアニメーションを追加してみました。
今日のQt勉強会で作ったもの。
— ayuma (@ayuma0913) 2018年8月25日
Qt3Dとフリー素材でサンプルを作ってみた。
少し味付けでマウスクリックでジャンプする仕組みを足してみた。#qtjp pic.twitter.com/onGR5UpqQ6
実装の中身
今回はC++は使わず全てQMLで書いてます。
車や建物の3Dモデル
やっている事はSceneLoaderのsourceにファイルを指定するだけで、あとはQtが勝手に読み込んでくれてます。便利!
車については、移動させたいのでTransformのtranslationの値を外から触れるようにプロパティにしてます。
rotationも指定してるのは、3Dモデルを普通に読みこむと横を向いちゃったので90度回転させてます。BlenderなどのモデリングツールでちゃんとQtと座標系をあわせてあげれば、これは必要ないとは思います。
余談ですが、普段Unreal Engine触っているのでX, Y, Zの座標系がいつもと違い戸惑いました。YとZがUnrealとQtでは逆でした。
- 車の3Dモデルを読み込む部分
Entity { components: [ SceneLoader { source : "/model3d/track.obj" }, Transform { id: myCarTransform property real locationX: 0.0 property real locationY: 0.0 rotation: fromAxisAndAngle(Qt.vector3d(0, 1, 0), 90) translation : Qt.vector3d(locationX, locationY, 0) } ] }
道路
地面と道路と白線は板ポリに色付きのマテリアルを貼って表現してます。
CoboidMeshっていうのが、立方体を表現するものでxExtent, yExtent, zExtentに大きさを指定してます。
マテリアルはPhongMaterialを利用して、とりあえず色(ambient)だけ指定してます。やけにテカった表現になってますが、その他のプロパティを使うとまた違った表現も作れるのかなとは思いますが今日の時点では未確認です。
- 地面
Entity { components: [ CuboidMesh { xExtent: 2000 yExtent: 0.1 zExtent: 500 }, PhongMaterial { ambient:"dimgray" }, Transform { translation: Qt.vector3d(0, -0.01, 0) } ] }
車の走る部分
NumberAnimation を使って、車のX座標を動かしてます。 -20mから1000mまで繰り返し設定です。 このfrom, toの値とdurationの関係で車速も狙った値にできます。
QQ2.NumberAnimation { id:moveAnimation target: myCarTransform property: "locationX" duration: 30000 from: -20 to: 1000 loops: QQ2.Animation.Infinite running: true }
ジャンプ
マウスのクリックでジャンプする部分ですが、実はこのクリックしたらという部分が最初実現できず悩みました。
通常の2Dの場合はMouseAreaを使っていたのですが、Qt3DのEntity内では利用できず、今はObjectPickerを利用しています。
でもこのObjectPickerで何故マウスイベントがとれているのかが、まだちゃんと理解できてないので今後ちゃんとしらべます。
マウスイベントをとったあとは、アニメーションのスタートに繋げてます。 ジャンプの上に上がるアニメと下に下るアニメをSequentialAnimationで繋げて表現しています。
ObjectPicker{ onPressed:{ myCar.notifyClick() } } function notifyClick() { jumpAnimation.start() } QQ2.SequentialAnimation { id:jumpAnimation QQ2.NumberAnimation { target: myCarTransform property: "locationY" duration: 500 from: 0 to: 3 easing.type: Easing.InSine } QQ2.NumberAnimation { target: myCarTransform property: "locationY" duration: 500 from: 3 to: 0 easing.type: Easing.OutSine onStopped: myCarTransform.locationY= 0 } }
まとめ
Qt3Dを使って簡単な3Dモデルの操作を実現することができました。
今日はタイムアップでできませんでしたが、あとはこんな事もやってみたいと思ってます。
- マテリアルのパラメータを変更して質感を色々変えてみる
- CuboidMeshでは真っ直ぐな道路しか作れないので、カーブの道路メッシュを作るためにはどうしたらよいか調査(OpenGL触るのかな?)
- ライトを調整して影とか変えてみたい