2015年07月22日

[Unity 5] テレポート移動のテスト [DK2]

酔わないようにテレポート移動しようの続きです。小さいキューブを動かすのも微妙でしたので、SDユニティちゃんに走ってもらうことにしました。キーボード入力でSDユニティちゃんに付けたカメラの位置にテレポート移動します。ステージはDecrepit Dungeonアセットを使用させていただいています。

手順メモ

1. GameObject→Cameraの追加:TagをMainCameraに(Main Cameraがなければ), Field of View:30, Clipping Planes: Near 0.01
2. GameObject→Light→Directional lightを追加(Directional lightがなければ)
3. Standard Assets→Characters→ThirdPersonCharacter→Prefabs→ThirdPersonController.prefabをDrag&Drop
4. Assets→Import Package→Custom PackageでSD_unitychan.unitypackageをインポート
5. ThirdPersonControllerにUnityChan→SD_unitychan→Prefabs→SD_unityChan_humanoid.prefabをDrag&Drop
6. EthanBodyとEthanGlassesを削除
7. ThirdPersonControllerのInspectorのAnimationのAvatarをSD_unitychan_humanoidAvaterに変更

実行してキーボードでSD_unitychanが動くことを確認

8. ThirdPersonControllerにCameraを追加:UnitychanCameraに名前変更
9. Assetsのどこかで右クリック→Create→Render Textureを追加:UnitychanRenderTextureに名前変更, 512x256に変更
10. UnitychanCameraのTarget TextureにUnitychanRenderTextureをDrag&Drop
11. Main CameraにGameObject→3D Object→Planeを追加
 Planeの位置(0.5, -0.5, 1.2), 角度(90, 180, 0), スケール(0.1, 0.1, 0.05), 各種Shadows: Off, Mesh Collider無効, ShaderはToon/Basicなど法線の影響を受けにくいものに変更
12. 追加したPlaneにUnitychanRenderTextureをDrag&Drop

実行してキーボードでSD_unitychanを動かして、SD_unitychan視点の映像がPlaneに映っていることを確認

unity_dk2_003.png

13. GameObject→CreateEmptyを追加:TargetPointに名前変更
14. Assetsのどこかで右クリック→Create→C# Scriptでスクリプトを作成:PlayerScriptに名前変更→Main CameraにDrag&Drop、中身は下記([1]の改変)
PlayerScript.cs
15. TargetPointをMain CameraのPlayerScriptのTargetにDrag&Drop

実行してキーボードでSD_unitychanがメインカメラの向きに移動することと、QとEでUnitychanCameraの上下向きが変わることを確認

16. GameObject→CreateEmptyを追加:Dummyに名前変更、Main Cameraの親にする
17. Assetsのどこかで右クリック→Create→C# Scriptでスクリプトを作成:TeleportScriptに名前変更→Main CameraにDrag&Drop、中身は下記
TeleportScript.cs
実行してTキーでUnitychanCameraの位置にテレポート移動することを確認

実行結果

Planeの背面が映りこんで赤になっちゃいますね。背面は描画しない設定にはなってないんですかね。
感想:
・キーボード入力で自発的にテレポートするためかカメラを急に切り替えても特に違和感はなかった
・右下のビルボードは視野全体からみると小さいのでそこでカメラが動いても(ずっと注視しなければ)あまり酔わない
・マウスでグイーンと視点回転などはないので酔いにくいはず
・自分で歩かないので没入感はあまりないかも

なおUnity 5は使い始めて10日程度なのでスクリプトの書き方とか色々間違っているかもしれません。
ユニティちゃんライセンス

このコンテンツは、『ユニティちゃんライセンス』で提供されています


[1] 040 カメラの向きに合わせてGameObjectを移動させる
web拍手 by FC2
posted by シンドラー at 06:44 | Comment(0) | TrackBack(0) | Unity 5 | このブログの読者になる | 更新情報をチェックする

2015年07月20日

Unityの勉強

3連休だったので、Unity 5をちょっと使ってみることにしました。目標はMikulusのようなものの作成です。

1. [1]を参考にシーンの作成
2. [2]を参考にMMD4Mecanim等を使用してTda式ミクさんの導入
3. FPSControllerでカメラ移動

Mikulusっぽいものをつくるのに[2]はとても参考になりました。[1]も前半はわかりやすかったです。あとはUnityのVR Supportにチェックをいれてとりあえず完成だったのですが、FPSControllerでの視点移動が微妙でした。

やっぱりDK2使う場合、その場で見回したりする分には問題ないですが、キーボードやマウス操作で視点が動くと酔いそうになります。そこで、カメラをもう一つ追加して、そのカメラを動かして位置決めして、その位置にメインカメラを瞬間移動させることにしました。

4. RenderTexture[3]を追加して、サブカメラから見た景色をメインカメラの子Planeに映す
5. サブカメラを操作して、位置を決める[4][5]
6. 特定のキーを押すと、サブカメラの位置姿勢をメインカメラの位置姿勢に設定
7. 特定のキーを押すと、サブカメラ等を無効化する[6]

実行結果
サブカメラ操作時
unity_dk2_001.png

メインカメラ移動結果
unity_dk2_002.png

参考資料
[1] Getting Started with Unity 5 - eBook
[2] 主婦ゆに!
[3] Unity 5で無料になった機能の使い方(4)
[4] [Unity]カメラ方向によって前方向を決める
[5] UnityをC#で超入門してみる #1 Unity入門の章
[6] Unity: GameObjectの非表示2つの方法と削除
web拍手 by FC2
posted by シンドラー at 20:39 | Comment(0) | TrackBack(0) | Unity 5 | このブログの読者になる | 更新情報をチェックする

2015年07月13日

Unity 5.1.1f1でAlembicImporterのメモ

今回はMMDBridge[1]で出力したAlembic形式をUnityで使ってみるテストです。Alembic形式の読込みにはAlembicImporter[2]を使用させていただきました。

MMDBridge側の操作
1. MMDBridgeのダウンロード(現在ver 0.65)
2. MikuMikuDanceにコピー(現在ver 9.26)
3. mmdbridge_alembic_for_houdini.pyをエディタで開く→is_use_ogawa = Falseに変更
 (AlembicImporterがogawa形式に対応していない?)
4. MMD/MMDBridgeを使ってAlembic形式で出力(法線、UV出力で1000フレームで2GB程度のファイルサイズ)
5. outにalembic_file.mtlとalembic_file.abcがあるのでAlembicImporter\Assets\StreamingAssets\AlembicDataにコピー
 (StreamingAssetsの中に置かないといけないらしい)
6. outにテクスチャもあるのでAlembicImporter\Assets\AlembicTestDataにコピー

Unity側の操作
1. AlembicImporterのダウンロード
2. AlembicImporter\Assets\Test.unityを開く
3. デフォルトのanimatedXformedMeshを削除
4. Assets→Alembic→importでAlembicData\alembic_file.abcを開く
5. とりあえず再生を押して動作確認→なぜか初期位置にモデルが残っている

alembic_unity_001.png

6. alembic_file.mtlとxform_0_materialを見比べると、マテリアル数が2倍(0〜16までなのに33まである)あるので、17〜33まで無効化(Inspectorの一番左上のチェックを外す)する

alembic_unity_002.png

7. alembic_file.mtlを見てAlembicImporter\MaterialsにMaterial作成とテクスチャの割り当てを行う。Shaderは適当にCustomシェーダを作成(参考[3][4]など)。透過がうまくいかなくてCutOutになった。

alembic_unity_003.png

MMDTransparent.shader (half-lambert + transparent cutout)

8. xform_0_material_○とmaterial_0_○をDrag&Dropで関連付け

alembic_unity_004.png

9. cameraがcamera_xformが優先されてMain Cameraが効いていないのでFPS Controller[5]にする

alembic_unity_005.png

9.1. camera_xformのcameraを無効化(Inspectorの一番左上のチェックを外す)する
9.2. Main CameraをDeleteする
9.3. Assets→Import Package→CharactersでStandard Assetsをインストール
9.4. Standard Assets\FirstPersonCharacters\Prefabs\FPSControllerを画面内のDrag&Drop
9.5. 位置や大きさを調整、上下移動が激しいのでUse Head Bobをオフにする

alembic_unity_006.png

とりあえずこれで踊っているTda式Appendミクさん[6][7]を移動しながら眺められるところまでできました。まぁMMD for Unityなどを使用するのが主流だとは思いますが。

[1] http://mmdbridge.render.jp/
[2] https://github.com/unity3d-jp/AlembicImporter
[3] http://panzersoft.blog.fc2.com/blog-entry-61.html
[4] http://famme-fatale.hatenablog.com/entry/2015/03/18/124410
[5] http://www.sugawara.ac.jp/digital/blog/gamecg-unity-semi/unity-1stscene-03
[6] http://3d.nicovideo.jp/works/td1586
[7] http://www.nicovideo.jp/watch/sm23692832

web拍手 by FC2
posted by シンドラー at 03:14 | Comment(0) | TrackBack(0) | Unity 5 | このブログの読者になる | 更新情報をチェックする

2015年07月09日

MeshLabのスクリプトについてのメモ

MeshLabは色々機能があって便利ですね。あまり知られていないかもしれませんが、MeshLabはコマンドラインからバッチ処理ができたりします。その処理内容についてですが、GUI上で行った操作をスクリプトとして出力できて、それをコマンドライン実行時に引数で指定してあげればいいという優れものです。

やり方については[1]に書かれています。

で、バッチ処理する際のバッチファイル(Windows用)のメモです。
  set PATH=%PATH%;C:\Program Files\VCG\MeshLab

  for %%V in (*.obj) do (
    meshlabserver -i %%V -o output\%%V -s default.mlx
  )
  pause
最初にmeshlabserver.exeがあるディレクトリへのパスを設定します。次に、そのディレクトリ内にある全ての.objファイルに、default.mlxで指定したフィルタリング処理を行って、outputディレクトリに出力する、ということをしています。

ファイルフォーマットの変換だけなら、スクリプトなしで下記のようなバッチファイルで行けます。
  set PATH=%PATH%;C:\Program Files\VCG\MeshLab

  for %%V in (*.ply) do (
    meshlabserver -i %%V -o %%~nV.obj
  )
  pause
ディレクトリ内の.plyを.objに変換するサンプルです。%%~nVで拡張子なしファイル名になるので、それに.objを付けてあげれば出力ファイル名になります。

[1] http://www.andrewhazelden.com/blog/2012/04/automate-your-meshlab-workflow-with-mlx-filter-scripts/
web拍手 by FC2
posted by シンドラー at 18:56 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2015年07月02日

OpenCVで海面生成のサンプル

いつの間にか7月ですね…。先月は忙しかった気がするので、今月はゆっくりしたいものです。

コメントに海面生成のソースが見たいという要望がありましたので、OpenCV 2.4.6ぐらいとfreeglutを使って作り直しました。時間が経っているので色々忘れていて困ったものです。

アルゴリズムとしては離散フーリエ変換による海面の生成 その1の参考文献に挙げている辺りです。一部のソースコードは参考文献のサイトのものをそのまま使っていた気がします。参考文献には特にライセンスに関する記述などは見当たりませんでしたが、もし問題があればどなたかお知らせください。また、OpenCVでFFTは[1]を参考にさせていただきました。

iOSということは携帯端末っぽいのでメモリとか計算時間とか厳しい気がしますので、事前計算してアニメーションメッシュに落とし込んでおくとか画像化しておくとかそういう工夫が必要そうです。

後バグがいろいろありそう(横幅と縦幅の文字を間違えていそうなところがあったので正方形(横幅=縦幅)以外ではエラーがでるかも)なので、気を付けてください。(このソースコードを使用して発生した如何なる不利益などについての責任を取りません)

以下ソース
opencv_ocean.zip

実行結果
opencv_ocean_001.png

シェーダもVBOも使わないシンプルワイヤフレーム表示しかしていません。

[1] http://opencv.jp/opencv2-x-samples/2d_dft_idft

web拍手 by FC2
posted by シンドラー at 18:00 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2015年06月09日

VOXファイルをMinecraftへImportするメモ

ちょっとだけMinecraftもやっていたので.voxをMinecraftに導入するためのメモです。(Minecraftでコツコツ作る楽しみが半減してしまいますのでオススメしません)

MagicaVoxel0.96では、slab形式のvoxでExportできます。(右下のExport→slab)Exportすると、Exportフォルダに○○.slab.voxというファイルができています。

このslab形式のvoxですが、slab6[1]というソフトウェアで読み込むことができます。File→Openで○○.slab.voxを開き、そのままFile→Save Asで○○.KV6で保存します。

続いて、kv6ToSchematic.jar[2]を実行します。Javaの実行環境が必要ですので、ダブルクリックしても起動しなければインストールしてください。とりあえず今回はUse Default Palette→Use Wool Blocksで羊毛として出力しました。後は○○.KV6を開いて、○○.schematicとして保存します。

最後に、MCEdit[3]でワールドをEditして、Importで○○.schematicを配置してSaveすれば完了です。

実行結果

MagicaVoxel[4]のサンプルをテストで読み込んでみました。問題がありましたらお知らせください。

minecraft_002.png

256x256x256のようなボクセルも一応試してみましたが、大きいのはちょっと大きすぎて微妙でした。

[1] http://advsys.net/ken/download.htm
[2] http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265323-kv6toschematic-import-3d-models-with-textures
[3] http://www.mcedit.net/
[4] https://voxel.codeplex.com/
web拍手 by FC2
posted by シンドラー at 02:26 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2015年06月04日

マウスでカメラ操作のテスト その2

以前の記事で極座標ベースのカメラ操作を実装していたのですが、マウス操作量に掛けるスケールは定数で、視野角やカメラから注視点までの距離などを考慮していなかったため、カメラパラメータによっては操作感が悪い状態でした。

そこで、その辺りのカメラパラメータを考慮したマウス操作量を検討してみました。

まずは平行移動量です。UpとRightベクトルは以前の方法で、それに掛けるスケールを1ピクセル分を基準に計算します。
mouse_view_001.png

次は回転です。シンプルですが、視野角などに依存しないのでこれで良さそうです。
mouse_view_002.png

最後はホイールでの距離操作です。これもシンプルなもので特に問題なさそうです。
mouse_view_003.png

実行結果


ボクセル化を行うなら、平行投影の方がいい気がしますが、今は透視投影で視野角小さ目でやっていたりするので、その辺は試してみますかね。
web拍手 by FC2
posted by シンドラー at 02:32 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2015年05月30日

PCLと深度バッファを用いたポリゴンモデルのボクセル化

とりあえずボクセル関係で出来そうなこととして、深度バッファを用いたポリゴンのボクセル化を試してみました。

流れ
1. モデル読込み
2. 最大長を指定して、読込んだモデルを囲むボクセルを生成(PCL)
3. Octreeを生成(PCL)

4. 1パスでカラー値と深度値をFBOに出力(OpenGL)
5. 2パスで、OctreeとRayが衝突した表面ボクセルのみを描画(PCL、OpenGL)
6. 3パスで1. と2. をMixして表示(OpenGL)

ここまでの結果
voxelize_001.png
カラーバッファだけの表示も可能
voxelize_002.png

7. 視点からRayを飛ばし、FBOの深度値を参照して深度値より手前にある色のついていないボクセルを削除、深度値付近のボクセルを、FBOのカラー値の色に設定。色を付けたことを示すためにラベルをインクリメント。(PCL)
8. OctreeとCloudの再構築(PCL)

正面から削除/色付けした結果
voxelize_003.png
前後方向から削除/色付けした後横から見た結果
voxelize_004.png

9. いくつかの視点から削除(PCL、OpenGL)

視点を変更することで、前後上下左右で隠れていた部分も削除/色付け可能
voxelize_006.pngvoxelize_007.png

10. 削除されていないかつ色がついていないボクセルを、近傍ボクセルに色がついていればその色に設定し、色がついたボクセルがひとつも見つからなければGUIで設定した基本色を設定(PCL)
(時間がかりすぎるので要最適化)
11. MagicaVoxelに対応している.voxもしくは.slab.voxファイルとして出力
 (.voxファイルは最大256色なので、パレットから似た色に変換)

実行結果
テストとして、[2]〜[4]のモデルを使用させていただき、ボクセル化してMagicaVoxelのレンダラで表示してみました。すべて最大長のボクセル数を512とした結果です。これより小さくするとナンバープレートが潰れたり微妙でした。計算はボクセル数多めにしておいて、出力時にうまく縮小するなどできるといいのかもしれません。

snap0000.png snap0001.png

snap0003.png snap0004.png

snap0002.png snap0005.png

ボクセル数が増えると使用メモリ量・処理時間ともに増えてなかなかつらいところです。

MagicaVoxelの.voxは8ビットと書いているように、ボクセルの座標も8ビット(0〜255)でしか指定できないので、最大でも255x255x255のサイズのボクセルしか構築できません。それ以上のサイズを使用する場合は、生データでサイズが大きくなりますがslabというファイルフォーマットを使用する必要があります。.voxのエクスポータを書いているとき、一部分しか出力されていなくて無駄に悩みました。

MagicaVoxelのレンダラで表示できるのはいいのですが、よく考えるとあまり使い道がないですね…。ポリゴンの方がきれいで軽いですし3Dプリンタなども使う予定はありませんし。マインクラフトとかに取り込めるんですかね。

メモ:マウス操作の操作性が悪いので改善する(距離に応じて移動/回転量を変更)

[1] http://www.naturalsoftware.jp/entry/2012/11/06/161132
[2] 軽自動車:http://seiga.nicovideo.jp/seiga/im4099340
[3] 頭蓋骨:http://flower-dam.com/wp/?p=3824
[4] らば式利根改二:http://www.nicovideo.jp/watch/sm24544789
続きを読む
web拍手 by FC2
posted by シンドラー at 13:07 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2015年05月25日

PCL 1.7.2のOctreeのテスト

Voxelで何かしようかなと思っているのですが、高速化のためにはOctreeなどデータ構造が大事かと思いますので、Point Cloud LibraryのOctreeを使用することにしました。本当はSparse Voxel Octreeのライブラリなどを使用した方がいいのだとは思いますので、機会があれば試してみたいと思います。

PCL 1.7.2の導入
公式は1.6.0のall-in-one-installersしかなかったですが、[1]で1.7.2のものを公開していただいていましたので、そちらを使用させていただきました。octreeのtutorialsは[2]にあります。今回必要なのはoctreeだけなので、includeやlibも最低限必要なものだけにしておきます。

インクルードのパス
$(PCL_ROOT)\include\pcl-1.7;
$(PCL_ROOT)\3rdParty\Eigen\Eigen3;
$(PCL_ROOT)\3rdParty\Boost\include\boost-1_57;

ライブラリのパス
$(PCL_ROOT)\lib;

ライブラリ(リリース)
pcl_octree_release.lib;

実行時に必要なライブラリ
$(PCL_ROOT)\bin\pcl_octree_release.dll

[3]を参考に、MagicaVoxelのVoxデータを読み込んでRaycastingで表示してみました。

ソースの一部(画像処理・レイの計算部分は省略)
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>

int rayCastTest(const int width, const int height)
{
    int hit = 0;

    MV_Model mv;
    mv.LoadModel("voxel/doom.vox");

    // ポイントクラウドの作成(色情報のためのラベルのためPointXYZLを使用)
    pcl::PointCloud<pcl::PointXYZL>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZL>);

    // 画像とレイキャスティングの準備は省略

    // voxデータからポイントクラウドを生成
    cloud->width = mv.voxels.size();
    cloud->height = 1;
    cloud->points.resize (cloud->width * cloud->height);

    for (size_t i = 0; i < cloud->points.size (); ++i)
    {
        cloud->points[i].x = mv.voxels[i].x;
        cloud->points[i].y = mv.voxels[i].y;
        cloud->points[i].z = mv.voxels[i].z;
        cloud->points[i].label = mv.voxels[i].colorIndex;
    }

    // octreeの生成、解像度はoctreeのボクセルのサイズ?
    float resolution = 1.0f;
    pcl::octree::OctreePointCloudSearch<pcl::PointXYZL> octree (resolution);

    octree.setInputCloud (cloud);
    octree.addPointsFromInputCloud ();

    // レイとボクセルの衝突判定
    std::vector<int> k_indices;

    Eigen::Vector3f org, target, dir;
    for (int y=0; y<height; y++)
    {
        for (int x=0; x<width; x++)
        {
            // 画素からレイの到達先を計算
            // 視点位置と到達先からレイの方向を計算

            // octreeとvoxelの衝突判定(1回)
            int ret = octree.getIntersectedVoxelIndices(org, dir, k_indices, 1);
            if (ret > 0)
            {
                // 今回は1個目のindex固定(解像度によってはk_indicesが複数Indexを含む)
                int label = cloud->points[k_indices[0]].label;
                // パレットから色を取得して画像に設定
                color.r = mv.palette[label].r;
                color.g = mv.palette[label].g;
                color.b = mv.palette[label].b;
                hit++;
            }
        }
    }
    // 画像の保存
    return hit;
}
実行結果(MagicaVoxel付属のサンプルdoom.vox使用)
pcl_test_001.png
ボクセル数2万弱、1024x1024の画像で、レイキャスティングの時間だけで400msぐらいでした。どちらかというと、全部のレイと衝突判定するのではなく、全部のボクセルを枝刈りしながらレイに当たるか判定する陰面消去的な探索がしたいのですが、どうやるんですかね。

[1] http://unanancyowen.com/?p=712
[2] http://pointclouds.org/documentation/tutorials/#octree-tutorial
[3] http://voxel.codeplex.com/wikipage?title=Sample%20Codes
web拍手 by FC2
posted by シンドラー at 00:56 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2015年05月23日

Oculus SDK 0.6.0.0とGLUTのテスト

Oculus SDKがv0.6.0.0になっていろいろ変わりましたので、GLUTでのテストをしてみました。
最近はSDKのサンプルにOculusRoomTiny(GL)がありますので、あまり必要ないのかもしれません。

1. Extended modeで動かない
こちらGTX690ですが、Direct display modeにしないと、サンプルとか今回のものとかが動きませんでした。

2. FBO2枚に分離
前は1枚のFBOの左半分に左目、右半分に右目を描画していたのですが、2つに分かれたみたいです。

3. Mirrorテクスチャも必要?
追加でMirror用のFBOが増えていて、そこに描画してから転送しているような雰囲気でした。

実行結果
ミラー画面をキャプチャした画像です。
oculusv0.6.0.0_001.png

Directモードのおかげか、ポリゴン1枚しか描画していないからかわかりませんが、追従遅れなどはほぼ感じなかったです。

以下ソース
main_glut_v0.6.0.0.cpp
simple.vert
simple.frag
OculusRoomTiny(GL)からの転用が多いので、その辺のライセンスになるかと思います。何か問題が起こっても責任はとりません。

web拍手 by FC2
posted by シンドラー at 03:13 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする