クロスプラットフォーム開発環境 Delphi / C++Builder で 3D表示のアプリを作る 

#統合開発環境 Delphi / C++Builder で 3D表示のアプリを作る （無償で使えるStarter Editionでも可能） 

クロスプラットフォーム開発環境 Delphi / C++Builder を使用して かんたんに 3D表示のアプリを作成する手順をご紹介します。
この一つの手順で、iOS, Android, Windows, macOSで動作するアプリを作れる事が魅力。

アプリ内で3D表示を行うことができれば、3D のモデリングや、3D空間のシミュレーションを行うなど、新しいアプリの利用方法が広がります。例えば小さな一部屋内での家具の配置を試すようなアプリを作ったり、大きな町一つを丸ごと、バーチャルリアリティの世界として作る、といったことにも利用できるでしょう。

Delphi / C++Builder を使った 最も基本的な3Dアプリ作成のチュートリアルは、エンバカデロのDocwikiに[「チュートリアル FireMonkey 3Dアプリケーションを作成する」](http://docwiki.embarcadero.com/RADStudio/Berlin/ja/%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%EF%BC%9AFireMonkey_3D_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)という題名で記載されています。より詳しい情報を知りたい方は、こちらのDocwikiもご参考になってください。

3Dモデルを作ったアプリの作成は、無料で使えるStarter Editionでも、Windows 32bit向け限定ではありますが、作成できます。よっ太っ腹！
Delphi / C++Builder の Starter Edition は[こちらの記事をご参考](http://qiita.com/kazaiso/items/1c0df8ff902405d1c214)に

すでにDelphi / C++Builder / RAD Studioをお持ちの方は、そのお持ちの開発環境でお試しください。お持ちでない方はトライアル版使って当記事内容を確認できます。トライアル版導入については、[こちらを記事をご参照](http://qiita.com/kazaiso/items/479fdf1170fa886fe208)あれ

##作成手順のビデオ
作成手順のビデオが公開されています。こちらもどうぞ

* [3Dアプリケーションを作成しよう Delphi編](https://youtu.be/CY-0Ci-BXt0)
* [3Dアプリケーションを作成しようC++Builder編](https://youtu.be/5zQffHvTOsM)

##3D地球儀アプリの作成手順
今回はいつもの、2Dアプリケーションフォームの上に、3D表示できる 3DViewPort といういわゆるレイヤーを張って、その中でライティングをしたり、3Dのブツを置いたり、3Dのブツに絵を張り付けて地球儀に仕立てあげ、かつその地球儀をアニメーションでくるくる回したりしてみます。

では実際の作成手順。

1. Delphi / C++Builderを起動し、最初に表示される ウエルカムページの 「マルチデバイスアプリケーション Delphi (C++Builder)の新規作成」を選択
1. 「マルチデバイスアプリケーション」のダイアログが現れたら「空のアプリケーション」を選択して[OK]ボタンをクリック
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/810cbc99-ef38-1ba6-4784-0604dc416974.png)
> ※ここでは「空のアプリケーション」（通常の2Dフォーム)を選択していますが、その右横の「3Dアプリケーション」を選んで、最初から3D表示のアプリを作ることができます。この場合、後述する 「3DViewPort」コンポーネントを張り付けずとも3DのShapesなどを表示することができます。最初から3Dアプリケーションフォームを使用している場合は、逆に、3Dフォームに対して、2Dコンポーネントを張り付けるための「TLayer3D」コンポーネントがあります。このコンポーネントの中に2Dコンポーネントたちを表示することができます。
今回の手順においては、一般的なアプリの作り方として、2Dフォームを使って、その中に3D表示レイヤー(T3DVirePort)をもち、3D世界を表現する方法をとっています 。

1. 3Dアイテムを表示するコンポーネントとして「TViewPort3D」を使用します。右下のツールパレットからフォーム上にドラッグアンドロップします。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/c0a488d0-802b-93c2-8ee9-2320c1365b32.png)
<br>
1. TViewPort3Dは「ViewPort3D1」という名称のコンポーネントとしてフォーム上に配置されます。この「ViewPort3D1」のプロパティのAlignにClientを設定して、ViewPort3D1の表示領域をフォーム全体へと引き延ばしておきましょう。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/f2708302-b0d8-b708-9278-ef64e216487f.png)
<br>
1. ついでに宇宙空間ぽく、色も変えます。プロパティのColorにBlackを設定しておきましょう。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/bf7b2e5b-f2e3-32a7-2c85-69a9d7b77ed6.png)
>※この「ViewPort3D1」内に3Dアイテムたちを配置できます。


1. 3Dのアイテムたちはツールパレットの3D関連のグループに収められています。まずは 3D Sceneグループ内の「TLight」をViewPort3D1上にドラッグアンドドロップします
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/4010e702-a379-8079-73bf-2e841fe0f8b0.png)
>※これは3Dのエリア内で、どの方向から光が照らされているか、を設定できるいわゆる光源を表しています。地球儀においては太陽の光の代わりです。今回はプロパティのRotation Angle のY軸に45を設定し、ななめ45度の水平方向から光が照らされているように設定してみましょう。
1. 「Light1」をクリックして選択し、左下のプロパティのRotationAngleの左横に表示されている[+]マークをクリックすると、X,Y,Zのサブアイテムが展開されます。このYに [45]を設定します。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/92b21c1a-06df-3512-4017-952275c3bc15.png)<BR>
ちなみにプロパティの「LightType」で一定方向からの照射を表すDirectionalや、点光源、スポットタイプなどを設定できます。今回はそのままDirectionalを使用します。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/cfd1d097-d27e-a043-4ad0-611168abbf7f.png)
<br>
1. 次に、地球儀そのものとなる球体、3D Shapesグループ内のTSphereをドロップします。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/56b301a1-bb82-001c-5628-ccad2ff97668.png)
<BR>
2. Sphere1のプロパティのDepthに[10]、Heightに[10]、Widthに[10]を設定して球体をより大きく変更しておきます。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/b3e1f6a3-a3c0-86a3-3f13-622580dd4271.png)
>3Dのモデルにくっついている水色のツマミをマウスでドラッグすることでも大きさを変更できます。今回は、きれいな球体をマウスで整えるのは困難なため、プロパティのDepth、Height、Widthに直接数値を入力して大きさを変更しました。<BR>
1. 地球儀は地軸が23.43傾いていますので、この球体 Shpere1 のプロパティ「RotationAngle.Z」軸も[23.43]ずらしておきましょう。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/ec1e7edd-9c73-66bf-3b3f-d01cdf07b8a3.png)
<BR>
1. 今度は、この赤い球体に地球儀のテクスチャ、つまり絵ですね。これを張って地球儀らしくしていきます。Materialsグループ内の「TLightMaterialSource」をドロップします。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/baf591c3-5820-3b92-ae13-f7575bc69fdd.png)
1. これを使うと、光源の影響をうけた明暗のある素材を張り付けることができます。LightMaterialSource1の プロパティ「Texture」の[BitmapEmpty]と表示されている部分を選択、ダブルクリックすると、「ビットマップエディタ」ダイアログが開きます。ここで「読み込み」ボタンをクリックして貼り付けたい写真、絵を選択してOKをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/b732f2b1-fc87-13df-8433-d9618c183b20.png)
>今回、NASAで無償提供している地球の2D画像を利用しました。[画像データはこちらで配布](https://visibleearth.nasa.gov/view.php?id=57752)されております。
ちなみに、雲の画像データも配布されており、これを透過GIFなどにして、この地球儀Sphere1の上にさらにSphereを子として載せて、雲のレイヤーとして表示する、などの発展もできます。[雲の画像データはこちら](https://visibleearth.nasa.gov/view.php?id=57747)
 

1. これで、LightMaterialSource1に地球儀の絵となる部分が読み込まれました。これを球体に張り付ける素材として登録します。Sphere1をクリックして選択して、プロパティの[MaterialSource]に先ほどの「LightMaterialSource1」を設定します。これでななめ45から光が照射されている陰影のある地球儀ができあがりました。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/07ef6193-cde9-22fb-c9dc-2241ca4f1065.png)
<br>
1. 球体が若干いびつです。もうすこし、細やかに表現するためにプロパティのSubdivisionsAxesを[32]、 SubdivisionsHeightを[32]に変更します。この数値を変更することでより細やかに3Dを表現できます。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/a1118612-e5ae-3d44-4120-7cc64a126fbc.png)
<br>
1. 次に、この地球儀をアニメーションさせて回します。 TFloatAnimationを使ってこの球体のY軸を継続的に変えてあげればよいのです。ツールパレットからTFloatAnimationをSphere1の上にドロップします。「構造ビュー」での表示ではこんな感じに、Sphere1の子としてFloatAnimation1が登録されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/9391aca4-1452-cee6-914c-b73c6641a08e.png)

1. FloatAnimation1のプロパティの「Duration]に[60]秒、「Enable」を[True]を設定してアニメーションを有効に、「Loop」を[True]にして繰り返しとして、「PropertyName」に[RotationAngle.Y]を指定して、水平方向にY軸の値をアニメーションするように設定します。
2. さらに「StartFromCurrent」 を[True]にして現在の値からアニメーションをスタートするように設定し、「StopValue」に[-360]として、球体の1回転分の値を設定します。
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/2167132a-f46e-3450-df87-e2a31bf5f3b0.png)
<BR>
1. またイベントハンドラの記述ももちろん可能です。Sphere1がクリックされたときに、ライティングの角度を変えるコードを記述してみましょう。左上の「構造ビュー」に表示されている 「Sphere1」をダブルクリックすると、Sphere1のクリック時のイベントハンドラのコード記述部にジャンプします。ここに TAnimaterクラスのAnimationFloatを使ってLight1のRotationAngle.Yの値を45度ずつ、0.5秒間でアニメーションするように記述します。

```delphi
//Delphiのコード
procedure TForm1.Sphere1Click(Sender: TObject);
begin
  TAnimator.AnimateFloat(Light1, 'RotationAngle.Y', Light1.RotationAngle.Y-45, 0.5);
end;
```

```cpp
//C++Builderのコード
//---------------------------------------------------------------------------
void __fastcall TForm1::Sphere1Click(TObject *Sender)
{
  TAnimator::AnimateFloat(Light1, "RotationAngle.Y", Light1->RotationAngle->Y-45, 0.5);
}
//---------------------------------------------------------------------------
```
これで実行[F9]キーを行うと、60秒かけて1周する3D地球儀が表示されます。クリックしてみると、ライティングが45度づつ変わっていきます。（動作イメージはこのブログ冒頭に引用している動画をご参照ください）

それでは3Dアプリの作成をお楽しみください。

##おわりに

ということで、3D表示アプリを作ってみました。
コンポーネントが用意されていて、結構かんたんにつくれてしまいます。

ここで紹介している手順より手を加えておりますが、Delphi版のソースコード（プロジェクト）をgithubに上げてあります。ご参考まで。
https://github.com/kazaiso/3DSphere
動作イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/145847/61fd7635-084f-2692-a428-fbadb0480e9e.png)

関連資料・参考資料
先人の方々には頭が下がります。ありがとうございます。

* [「誰でも始められるカンタン
FireMonkey 3D 入門 : 慶應義塾大学 大学院理工学研究科 藤代研究室
研究生 中山雅紀 様](http://edn.embarcadero.com/print/images/43547/b1.pdf)
* [FireMonkey で作る地球儀 ～ 多分、4 分以内に ～ : Hideaki Tominaga 様 (Youtube)] (https://www.youtube.com/watch?v=elZt84EzygY)