2018年06月11日

glTFのテスト その2

とりあえず読込みできるようになったので、前から作っているGUIに組み込んでみました。
テクスチャがおかしかった問題ですが、モデルによっては頂点カラーのみで、テクスチャ座標を持たないメッシュがあり、こちらで使っている中間データは頂点数=テクスチャ座標数で考えていたので、テクスチャ座標を持たないメッシュがあるとインデックスがずれてしまっていたのが原因でした。

実行結果

いくつかsketchfabのデータを表示してみましたが、大体は問題なさそうです。今回は[1]のデータを表示させていただきました。

glTF_test_002.png

[1] https://sketchfab.com/models/011dc1e272be4245bfe2f7e72503f6ab#
web拍手 by FC2
posted by シンドラー at 22:19 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2018年05月31日

glTFのテスト

いつの間にか5月が終わりましたね。何となくglTF[1]対応をしてみようと思いました。
Khronos Group提唱ですので、OpenGLとの親和性が高そうですね。

今回は[2]のライブラリを使用させていただいて、とりあえずファイルを読み込んで.objに変換してみました。
nodeにmatrixやquaternion等の情報が親子関係で定義されていて、そこにmeshが関連付けられています。
meshにはmaterialやaccessorが関連付けられていて、bufferやimagesから各種データを取り出すことができます。
positionはオブジェクト座標ですので、nodeに記述されている位置姿勢を掛けていく行列操作も必要です。

実行結果

sketchfabというサイトではモデルを全てglTFで保存できるようになっているようで、今回は[3]のモデルをテストとして使用させていただきました。行列掛ける順番間違えたり結構苦労して、まだテクスチャ座標がおかしそうですが、とりあえずMeshLabで表示できたので、おおよその読み込みはできたと思います。

glTF_test_001.png

[1] 次世代の3Dデータフォーマット決定版 glTF 2.0 の概要図を日本語訳してみた
[2] Header only C++ tiny glTF 2.0 library
[3] sketchfab - Oculus Rift CV1
web拍手 by FC2
posted by シンドラー at 22:27 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2018年04月30日

SFMLのテスト その4

いつの間にか4月が終わりますね。5x5では狭いので15x15に広げてみました。後はCSVファイルを読み込めるようにしてみました。解き方も色々工夫できそうですが、なかなかアルゴリズム考えるのも難しいですね。

実行結果

参考として[1]の問題を使わせていただきました。簡単な問題しか解けませんね。

sfml_tgui_001.png
CSV読込み

sfml_tgui_002.png
1回目

sfml_tgui_003.png
2回目

[1] https://www.minicgi.net/logic/
web拍手 by FC2
posted by シンドラー at 18:35 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2018年04月04日

SFMLのテスト その3

TGUIのテストです。お絵描きロジックを自動で解くプログラムでも作ってみようということで、GUIを作ってみました。数値を入力するためのEditBoxと、塗りつぶす所と除外する所の画像を切り分けたかったので、BitmapButtonを使うことにしました。

TGUIにはgui-builderというソフトウェアが付いていますので、基本的な配置はこれを使って行って、後はテキストを編集すると早いかもしれません。

TGUI_002.png

form.txtなどのテキストファイルに出力すると、プログラムから読み込むことができます。
    gui.loadWidgetsFromFile("form.txt");
後はconnect使ってコールバック関数を実装すれば良いかと思います。Gridというクラスがあったので、これを使えば今回のようなプログラムには有効そうでしたが、今のところ無理やりGUIのポインタ経由で操作しています。

後はExampleのMany different widgetsで使われていますが、Themeを使うと比較的楽に部品の設定ができる気がします。

実行結果

TGUI_003.png

とりあえず各行と各列をチェックして、5の時は全部埋めて、0の時は全部×を付ける処理だけ実装しました。ちゃんと解こうとすると大変そうですが、5x5だとあまりパターンもないので楽かもしれません。



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

2018年03月31日

SFMLのテスト その2

SFML対応のGUIの一つであるTGUI[1]を試してみました。スライダーやボタン、エディットボックスなど色々使えるみたいです。

CMake使ってソースからコンパイルしてもいいですが、バイナリもダウンロードできます。今回は手軽にバイナリから使いました。サイトにチュートリアルや例題があるので、それを見れば特に問題はないかと思います。

実行結果

例題のScalable login screenです。背景画像はLenna画像に差し替えました。

tgui_test_001.png

いつも使っているTweakBarは、どちらかというとメニュー優先っぽいので、ボタンやエディットボックスを含むGUIを手軽に使いたい場合は良いのではないでしょうか。

[1] TGUI: Texus' Graphical User Interface
web拍手 by FC2
posted by シンドラー at 22:03 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2018年01月20日

SFMLのテスト

結局使いませんでしたが、お絵かきロジックのソフトウェアをSFMLで作ろうかなと考えていたのでサンプルまでの手続きをメモっておきます。

SFMLはマルチメディアライブラリで、下記のモジュールで構成されています。
System:
コアモジュールです。2次元及び3次元ベクトルクラス、時計、スレッド、Unicode文字列などを提供します。
Window:
アプリケーションウィンドウを作成できます。マウスやキーボードなどのユーザ入力を扱えます。
Graphics:
画像やテキスト、形状や色など2次元の描画機能を提供します。
Audio:
音楽の読込やスピーカを使った再生などの機能を提供します。
Network:
ネットワークもカバーしており、HTTPやFTPのプロトコルでLANやインターネットを通じてデータを送ることができます。

モジュールの詳細についてはドキュメントを参照してください。
http://www.sfml-dev.org/documentation.php

SFMLはオープンソースで、ライセンスはzlib/libpngライセンスです。商用/非商用どちらでも使用できます。

ダウンロードとインストール
ビルド済みのライブラリをダウンロードするか、ソースコードをGitなどから取得してコンパイルすることもできます。
CMakeを使ってVisual Studio用のソリューションファイルを作成することもできます。これらの手順は下記の場所にチュートリアルがあります。
http://www.sfml-dev.org/tutorials.php

今回はCMake GUIを使ってVisual Studio 2013のプロジェクトファイルを作成しました。スタティックリンクにしました。
ソリューションを開いてALL_BUILD→INSTALLすると、インストール先に設定したディレクトリにincludeやlibが作成されます。

A minimal example
参考文献[1]のサンプルそのままです。
#include <SFML/Graphics.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
    sf::RenderWindow window(sf::VideoMode(640, 480), "SFML Application");
    sf::CircleShape shape;
    shape.setRadius(40.f);
    shape.setPosition(100.f, 100.f);
    shape.setFillColor(sf::Color::Cyan);
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear();
        window.draw(shape);
        window.display();
    }
    return 0;
}
ビルド時の注意点
今回はスタティックリンクにしましたので、プリプロセッサのところにSFML_STATICを入れる必要があります。
SFMLのモジュールのライブラリは基本的には下記のものがあります。

sfml-audio-s.lib
sfml-graphics-s.lib
sfml-main.lib
sfml-network-s.lib
sfml-system-s.lib
sfml-window-s.lib

-sはスタティックの場合について、デバッグバージョンはさらに-dが付きます。
今回は上記のものだけでは足りなかったので、下記もリンクさせました。

opengl32.lib
jpeg.lib
winmm.lib

オーディオ関係を使う場合には、さらにopenal32.lib/openal32.dllが必要になるなど、状況に合わせて追加する必要があります。

実行結果

sfml_001.png

サンプルなので円が表示されているだけです。
web拍手 by FC2
posted by シンドラー at 02:30 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2017年12月28日

お絵描きロジックのテスト その3

昨日の続きです。

下記のような流れで画像からお絵描きロジックの数値に変換しました。縮小しているだけなのでもう少し工夫したいところです。

1.ファイルオープンダイアログを使って画像の選択・読込み
2.25x17に縮小
3.大津の2値化で2値化
4.白画素の数を数えて問題を作成
5.正解したらタイムを表示して終了

4.のコードは下記のような感じです。
piclogic_006.png

実行結果

フリーアイコンの画像などで試してみました。

piclogic_005.png
piclogic_007.png
piclogic_008.png

最後ピラミッドの写真か何かですが全然わからないですね。一応一通りの動作を3日で作れたので思ったより早かったです。
web拍手 by FC2
posted by シンドラー at 16:56 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2017年12月27日

お絵描きロジックのテスト その2

昨日の続きです。

スタティックテキストのUIを追加しました。あまりお絵描きロジック固有のクラスにはしたくなかったのですが、

1
10
5

のように、縦書きだけれど各行は横書きみたいなこともできるようにしたら少し特殊になりました。

piclogic_003.png

実行結果

サンプルはネットで探したものなので著作権的に問題があるかもしれません。

piclogic_004.png

とりあえずUI的にはできた気がしますので、後は画像を読み込んでエッジ抽出して問題作成とかその辺を試してみたいと思います。
web拍手 by FC2
posted by シンドラー at 21:42 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

お絵描きロジックのテスト その1

気が付くと年末です。最近あまりプログラム書いていなかったので、リハビリとしてお絵描きロジックでも作ろうと思います。

最近使っているGUIであるAntTweakBarは、あまり今回のようなボタンは向いていないと思いますので、他のUIライブラリを使用することを考えていました。UIライブラリについては[1]が参考になります。

ただ、ユーザインタフェースとしては、画像とボタンと数字の表示ぐらいなので、他のライブラリを準備せずに自前で作ることにしました。

piclogic_000.png

一応汎用性を持たせるために、クリックされたときの動作は関数ポインタを渡すようにしました。今回で言えば一回塗りつぶしたマスをもう一回クリックしたら初期状態に戻すとかそういった細かい動作を別関数で定義してボタンクラスに渡します。

実行結果

piclogic_001.png

割とあっさりできました。後はドット絵でも読み込んで数字表示してゲームとして動くようにしたいと思います。

[1] OpenGL な UI を作るライブラリ一覧
web拍手 by FC2
posted by シンドラー at 00:43 | Comment(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2017年07月05日

凸多面体の内外判定について その2

とりあえず画像処理ソフトの方に組み込んで試してみました。

実行結果

いつ作ったのか覚えてないですが、良さそうな画像があったので試してみます。
circles.png
入力画像

drag_test_006.png
一番大きい円の色と思われる辺りを囲んだ結果

drag_test_007.png
右下の円の色と思われる辺りを囲んだ結果

HSV変換した分布領域を多面体で囲んで、領域内の色は白、それ以外は黒で2値化しています。色が似ていても(線形分離可能であれば)うまくいきそうです。複数領域選択とかできればもっとやりやすそうですが面倒ですね。

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

2017年07月04日

凸多面体の内外判定について

2値化の範囲を決定する際に、数値で刻んで矩形領域を設定するのは効率が悪いし自由度も低いので、その辺をマウスでできるようにしようかなと思いました。

直方体の8頂点をマウスでドラッグできるようにするのですが、自由に動かすと凹面ができてしまいますので、各面の中心に頂点を追加して、面が凹面になる場合にはこの中央点を移動させて無理やり凸面に修正するようにしました。

マウスドラッグで頂点移動はこれまでもやってきたような行列変換でできます。

drag_test_001.png
drag_test_002.png
drag_test_003.png
PPTで作ってみましたが見づらいですね。

実行結果
drag_test_004.png
透視投影変換を基準にしているので直感性は低いかと思います。こういう矩形の選択には正射影が向いていそうです。

続いて点の内外判定についてです。直方体の頂点を移動させた凸多面体ですので、それぞれの面が構成する平面と点の内外判定を行えば判定できると思います。点と平面の距離などは以前のスライドに追記しました。


実行結果
drag_test_005.png

ちゃんと選択した範囲のみ青くなっているので合っているとは思います。点群がRGBやHSVなど画素の色を3次元空間に投影したものを考えていて、それをこういうやり方で範囲選択できれば2値化がうまくできるのではないかと思っていますが、それはこれから試してみる予定です。

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

2017年06月08日

キューブマップとスフィアマップの作成

キューブマップとかスフィアマップとか出てきたのでパノラマ画像[1]をキューブマップやスフィアマップに変換するプログラムを作成してみました。

キューブマップは球面調和関数を試していたころに作っていた関数があったのでそのまま使用しました。積分などは行わずに極座標変換してレイが当たったところの色をそのままとっていたと思います。

スフィアマップの方は[2]を参考にさせていただきました。細かい話ですが、ray[2]とray[3]はray[1]とray[2]の間違いですね。ちゃんと見ていませんが、fire_ray関数の実装はなさそうでしたので、rayをワールド座標に見立てて、それを極座標に変換してキューブマップと同じ方法で変換してみました。

実行結果

cubemap_001.png
HDR画像を開いた後です。一応輝度値の最小/最大も表示するようにしています。255が1.0になるようにしているので、普通の画像は0〜1になります。

cubemap_002.png
キューブマップ変換後です。1枚にまとめたものと、各方向個別の6枚も出力するようにしました。

cubemap_003.png
スフィアマップ変換後です。これで合っているのかどうかはいまいちわかりませんが、[3]のミラーボールに似た結果になっているので良いことにします。

参考サイト
[1] http://vgl.ict.usc.edu/Data/HighResProbes/
[2] ftp://ftp.sgi.com/opengl/contrib/blythe/advanced99/notes/node179.html
[3] http://steradian.co.jp/adv3d/3dcg/HDRShop/PanoramicImage.html

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

2017年06月07日

四角ポリゴンの三角ポリゴン化

Oculus Mediumというソフトウェアを試してみたのですが、3次元空間でのお絵描きというのも新鮮でいいですね。MediumでObjファイルをStampとして空間に描くことができるのですが、少し前のバージョンでは四角ポリゴンがあったり法線ベクトルがなかったりするとエラーで読み込めませんでした。最新バージョンでは直したみたいです[1]。

以前他のレンダラ用の変換プログラムを作っていた気がしたので、それに四角ポリゴンを三角ポリゴンに変換する機能も入れました。やり方自体は簡単です。QUADの場合、indexに4頂点が指定されていますので、3頂点×2個の面に分割して追加するだけです。

quad2triangles_001.png

一応四角ポリゴンの.objを読み込んで出力してみましたが、きちんと三角ポリゴンになっていました。この変換プログラムは輪郭線の描画は画像処理でやっていたので、遅かったのでOpenMPを試してみました。parallel forしか使っていませんが、体感的には2倍ぐらい早くなった気がします。ついでに過去の記事でやっていたブルーム効果も追加してみました。

実行結果

render_blume_001.png
キューブマップを導入したら動くPCと動かないPCがあって謎です。キューブマップ単体のサンプルなら表示されるので、テクスチャ周りの使い方に何か問題があるんだと思うのですが…。

[1] Oculus Medium Updates

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

2016年09月27日

Alembic形式の読込みに関するメモ

MMDBridgeなどでAlembic形式が使われていますので、Alembicのライブラリのコンパイルとか使用方法のメモです。最初は[2]を参考に、HDF5を使ったAlembicファイルを読み込んでいたのですが、なぜか1000フレームを超えるデータを読み込もうとするとエラー終了してしまうので、諦めてOgawa形式のAlembicファイルを使用することにしました。MMDBridgeでは、mmdbridge_alembic_for_houdini.pyをそのまま使っています。

Alembicのホームページは[1]にあります。SourceをクリックするとGitHubのページに移動しますので、そこからソースコードをダウンロードします。必要なのかどうかわかりませんが、ilmbaseのライブラリも準備しました。これは以前OpenEXRの準備をしたときに作っていたものを使用しました。

Alembicのコンパイルは、CMakeを使ってやりました。generate先はbuild64というディレクトリを作成してそこにソリューションファイルを生成するようにしました。設定した項目は下記の感じです。

ilmbaseのライブラリやインクルードディレクトリの設定
ALEMBIC_ILMBASE_HALF_LIB
ALEMBIC_ILMBASE_IEXMATH_LIB
ALEMBIC_ILMBASE_IEX_LIB
ALEMBIC_ILMBASE_ILMTHREAD_LIB
ALEMBIC_ILMBASE_IMATH_LIB
ILMBASE_INCLUDE_DIR

USE_HDF5などもあるのですが、最初に書いたようにうまくいかなかったので今回はOFFのままにしました。後はVisual Studioを起動してビルドすれば、Alembic.libができているはずです。

使用方法

ライブラリを使用する場合の設定です。Cドライブに直入れしている場合の例なので適当です。

追加するインクルードディレクトリ
C:\alembic-1.6\lib
C:\alembic-1.6\build64\lib
↑ Config.hのために必要
C:\OpenEXR\include

追加するライブラリディレクトリ
C:\alembic-1.6\build64\lib\Alembic\Release
C:\OpenEXR\lib
追加するライブラリファイル
Alembic.lib

ソースコードの一部
#include <Alembic/AbcCoreAbstract/All.h>
#include <Alembic/Abc/ErrorHandler.h>
#include <Alembic/Abc/All.h>
#include <Alembic/AbcGeom/All.h>
#include <Alembic/AbcCoreOgawa/All.h>

using namespace Alembic::Abc;
using namespace Alembic::AbcGeom;

...

  // Ogawa形式のAbcファイル読込み
  Alembic::Abc::IArchive archive(Alembic::AbcCoreOgawa::ReadArchive(), FileName);
  Alembic::Abc::IObject obj = archive.getTop();
  // 子データ数の取得
  unsigned int numChildren = obj.getNumChildren();
  std::cout << "found " << numChildren << " children in file\n";

  // 子データの数だけ繰り返し
  for (int i = 0; i < numChildren; ++i)
  {
    // 子データのオブジェクトを取得
    IObject child(obj, obj.getChildHeader(i).getName());
    // さらに子データの数を取得
    std::cout << "Children " << child.getNumChildren() << "\n";
    const MetaData &md = child.getMetaData();
    std::cout << md.serialize() << "\n";

    // 子データが見つかった場合
    for (int x = 0; x<child.getNumChildren(); x++)
    {
      // 子データのオブジェクトを取得
      IObject child2(child, child.getChildHeader(x).getName());
      const MetaData &md2 = child2.getMetaData();
      std::cout << md2.serialize() << "\n";

      // 子データがメッシュデータの場合(今回はカメラの時は未処理)
      if (IPolyMeshSchema::matches(md2) || ISubDSchema::matches(md2))
      {
        std::cout << "Found a mesh " << child2.getName() << "\n";
        // we have a mesh so build a mesh object
        IPolyMesh mesh(child, child2.getName());
        // grab the schema for the object
        IPolyMeshSchema schema = mesh.getSchema();

        // now grab the time sample data for the object
        IPolyMeshSchema::Sample mesh_samp;
        // ISampleSelectorを使って取得するフレームを設定する(今回は11200番目のフレーム)
        // HDF5だと1000以上の値を設定するとなぜかエラーが発生した
        ISampleSelector ss(Abc::index_t(11200));
        schema.get(mesh_samp, ss);
        // get how many points (positions) there are
        Alembic::Util::v8::uint32_t size = mesh_samp.getPositions()->size();
        // 面数の取得
        Alembic::Abc::Int32ArraySamplePtr faceNum = mesh_samp.getFaceCounts();
        // 法線情報の取得
        IN3fGeomParam N = schema.getNormalsParam();
        // we didn't set any on write, so on read, it should be an invalid container
        // getExpandedValue() takes an optional ISampleSelector;
        // getVals() returns a TypedArraySamplePtr
        N3fArraySamplePtr nsp = N.getExpandedValue().getVals();
        // UV情報の取得
        IV2fGeomParam uv = schema.getUVsParam();
        IV2fGeomParam::Sample uvsamp = uv.getIndexedValue();
        std::cout << "size=" << size << ", faceCount=" << faceNum->size() << "\n";
        // 面の数だけ繰り返す
        for (Alembic::Util::v8::uint32_t m = 0; m < size; ++m)
        {
          // get the current point
          V3f p = mesh_samp.getPositions()->get()[m];
          N3f Normal = nsp->get()[m];
          V2f uv2 = (*(uvsamp.getVals()))[m];
          // 以上で頂点座標/法線ベクトル/テクスチャ座標を取得
        }
        for (Alembic::Util::v8::uint32_t m = 0; m < faceNum->size(); ++m)
        {
          unsigned int index[3];
          // get the current face
          for (int k = 0; k < 3; k++)
          {
            index[k] = mesh_samp.getFaceIndices()->get()[3 * m + k];
          }
          // 以上で頂点インデックスを取得
        }
      }
    }
  }

  ...

基本的に[2]を参考にさせていただいて、Alembic 1.6でちょっと仕様が変わっている感じです。

実行結果

AlembicTest_001.png

変換のサンプルがAlembicに入っているので意味はないですが、Alembicを読み込んでObjで出力してMeshLabで表示したものです。Tda式ミクさんとマリエルさんステージを使用させていただいております。

[1] http://www.alembic.io/
[2] http://jonmacey.blogspot.jp/2011/12/getting-started-with-alembic.html

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

2016年06月02日

平面の方程式に関するメモ

前回のソースコードで自分で追加した部分に関するメモです。間違っていたら教えてください。



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

2016年05月31日

libiglの使い方メモ その4

いつの間にか5月も終わりですね…。来月からはもう少し更新するようにしたいです。今回は前回の続き+αで、展開したテクスチャにAO計算した結果を焼き込んでみました。

1. Camelheadを読み込む
2. 前回と同じ方法でUV展開
3. Example 606を参考にAmbient Oculusionの計算
4. 各ポリゴンのテクスチャ画像上の座標とAO値を3次元ベクトル(tx*texSize, ty*texSize, ao)としてラスタライズ[1]〜[3]
5. テクスチャにラスタライズ結果のAO値を出力
6. UV値やテクスチャ情報を含むモデルとしてCamelheadを出力

ラスタライズに関しては、[3]のものをEigenを使ったものに書き換えたのと、[2][3]を参考にz値を補間するように追加しました。注意点としては、今回参考にしたラスタライザはおそらく右手系、ポリゴンは反時計回り順を想定していますので、テクスチャ座標も左回りになるように外積を使って判定する必要があります(頂点座標が左回りでも、対応するテクスチャ座標が左回りになっているとは限りません)。判定して右回りの場合は、ラスタライザに渡す頂点の順番を入れ替えます。

実行結果

CamelheadのテクスチャとしてAO情報を出力した結果
libigl004_camelhead1.png

MeshLabで出力したテクスチャ付きモデルを表示した結果libigl004_camelhead2.png
光源なし・テクスチャなし
libigl004_camelhead3.png
光源なし・テクスチャあり
libigl004_camelhead4.png
光源あり・テクスチャあり

耳や口のあたりはテクスチャ展開の結果の影響もあってあまりきれいじゃないですね。目の周りあたりはそれなりにうまくいっている気がします。

[1] http://ushiroad.com/rasterizer-refs/
[2] http://memo.render.jp/tekitou-hon-yaku-memo/re
[3] http://forum.devmaster.net/t/advanced-rasterization/6145
続きを読む
web拍手 by FC2
posted by シンドラー at 18:28 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2016年04月30日

libiglについてのメモ その3

いつの間にか4月が終わって5月ですね。困ったものです。月1回は更新しておきたいので小ネタです。チュートリアルの501〜503ですが、UV展開のようなサンプルがあります。ただ、サンプルのcamelhead以外では、boundary_loopの所でエラー終了してしまうので、凸包など、何か適用できる条件があるのかもしれません。

harmonic関数で、展開したUVの計算ができるようです。その際、5番目の引数で展開方法が選べるようです。
(1: harmonic function, 2: biharmonic, 3: triharmonic, ...)

igl::harmonic(V, F, bnd, bnd_uv, 1, V_uv);

実行結果

数値を変えて画像として出力した結果です。V_uvは各頂点のUV座標ですが、0〜1の範囲ではなく、今回の結果では-1.2〜1.1等中途半端な値になっていましたので、適切に0〜1の間にマッピングする必要がありそうです。


libigl_camelhead1.png libigl_camelhead2.png libigl_camelhead3.png
   1: harmonic      2: biharmonic      3: triharmonic

次はAOを計算してテクスチャに焼き込むテストでもするかもしれません。

[1] http://libigl.github.io/libigl/tutorial/tutorial.html
web拍手 by FC2
posted by シンドラー at 23:20 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2016年03月04日

libiglについてのメモ その2

前回の続きです。

とりあえずExample 203を参考に、その他のモデルで曲率とベクトルを計算してみました。その際、下記のようなエラーが出ました。

Could not compute curvature of radius 0.827856

エラーで検索してみると、重複する頂点があると失敗するので、igl::remove_duplicate_verticesを使って先に削除するように書かれていました[1]。

使い方ですが、下記のように使用します。
#include <igl/remove_duplicate_vertices>
...
  MatrixXd SV;
  MatrixXi SVI, SVJ;
  // 重複頂点の削除
  igl::remove_duplicate_vertices(V, 0.0000001, SV, SVI, SVJ);
  // SVに削除後の頂点
  V = SV;
  // SVJに元の頂点番号→削除後の頂点番号が格納されているので、
  // インデックスリストを更新
  // ループを回さず一括処理する方法があるはず?
  for (int i = 0; i < F.rows(); i++)
  {
    for (int j = 0; j < F.cols(); j++)
    {
      int temp = F(i, j);
      F(i, j) = SVJ(temp);
    }
  }
関数の引数としては、一つ目が頂点の位置座標行列、2つ目が重複判定のためのパラメータ、3番目が削除後の頂点の位置座標行列、4番目が、削除後の頂点番号→削除前の頂点番号のマップ、5番目が削除前の頂点番号→削除後の頂点番号のマップになります。これを使用して、面のインデックスを更新します。

実行結果

あぴミクさんをOFFに変換してテストしてみました。OFFというのは初めて見ましたが、3D CADなどで使われているファイルフォーマットのようですね[2]。

libigl_015.png

頂点を削除したくない場合は、削除前/削除後のマップは用意されていますので、計算するときだけ一時的に削除して、元の接線ベクトル/従法線ベクトルに割り当てるといった使い方はできるかと思います。

後、結果としては結構統一性がない気がするので、可視化にこれを使うと色々問題があるのかもしれません。頂点単位ではなく、テクスチャ単位で欲しい気もします。

[1] principle_curvature "Could not compute curvature" on STL file
[2] Wikipedia - OFF (fileformat)
web拍手 by FC2
posted by シンドラー at 00:30 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2016年03月01日

libiglについてのメモ

いつの間にかもう3月ですね。2月は29日があったのにすぐ終わった気がします。

頂点座標に法線ベクトルは一般的に用意されていますが、接線ベクトルは用意されていない場合が多く、外積を使用したりテクスチャ座標から計算したりすることが多いです。頂点座標と法線ベクトルから計算できるのは接平面であり、ベクトルとしては無数に取れるため、どの方向を接線ベクトルとして採用するかが問題となります。

この辺を、例えば近傍頂点から曲面を推定し、勾配などから決める方法はないのかなと考えてみたところ、libigl[1]というライブラリを使えば良さそうな気がしました。ヘッダオンリーのC++ジオメトリ処理ライブラリで、MPLv2.0ライセンスのものです。内部でEigenを使っているようです。

[1]のリンクにもありますが、Tutorial[2]があり、かなり充実しているようですので、そちらを参考にすれば色々できると思います。

0. Mesh representation (Example 101)

libiglでは、Eigenライブラリを使用しており、ベクトルと行列を使用します。三角メッシュの頂点と面情報も行列のペアで表現されます。
    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
Vは、頂点数×3(x,y,z座標)の行列で、Fは面数×3(面のインデックス(左回り))の行列のようです。こうすることで3つぐらいいいことがあるそうです。libiglでは一般的なメッシュフォーマットの読み書きはサポートしていて、read*.hやwrite*.hなどのファイルに記述されています。

libigl_001.png
[1]より引用した説明図

1. Curvature directions (Example 203)

ガウス曲率を計算する時の最大と最小の曲率を持つ主曲率の方向を計算できるようです。この2つのベクトルの片方を接線ベクトル、もう一つを従法線ベクトルにすれば、今回の目的は果たせそうではありますが、その結果がいいものなのかどうかは不明です。

実行結果

libigl_014.png

2. Baking ambient occlusion (Example 606)

レイキャスティングによる頂点ごとの環境遮蔽を計算してくれる関数が提供されています。使用する場合、外部ライブラリとしてEmbree[3]が必要でした。

実行結果

libigl_013.png

この他にも、DualQuaternionSkinningとか面白そうな機能がたくさんあります。

[1] GitHub - libigl
[2] libigl tutorial notes
[3] Embree - High-performance ray tracing kernels
web拍手 by FC2
posted by シンドラー at 22:55 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2015年11月24日

PolyVoxの使い方についてのメモ

いつの間にか11月下旬ですね…。もう来月で一年が終わってしまうとは困ったものです。
以前の記事でも使っていましたが、PolyVox[1]をMinecraft風に使う場合のメモです。

PolyVoxでは、表面ポリゴン抽出を、マーチングキューブス法を使ってなるべく滑らかな表面を作成する方法と、Minecraftのように立方体が積み重なったような表面を作成する方法のどちらかを選ぶことができます。

CubicSurfaceExtractorWithNormalsでは、ボリュームデータから表面ポリゴンを立方体ベースで作成してくれます。このとき、ポリゴン情報とボリューム格子番号の対応が取れないっぽいのですが、マテリアル番号は格納されているようです。

まず、Minecraft風のボリュームデータでは、各格子が持つデータ1バイト(0〜255)をマテリアル番号として、0を空気、それ以外を物体とします。今回は例題としてMagicaVoxel[2]のサンプルデータを読み込んで、それをボリュームデータとしてそのまま適用しました。

で、ポリゴンデータはチュートリアル[3]にもあるように、下記3行で抽出できます。


  SurfaceMesh<PositionMaterialNormal> mesh;
  CubicSurfaceExtractorWithNormals< SimpleVolume<uint8_t> >
    surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
  surfaceExtractor.execute();

次に、頂点座標やマテリアル番号の参照方法ですが、こちらもチュートリアルを参考にします。

  //Convienient access to the vertices and indices
  const vector<uint32_t>& vecIndices = surfaceMesh.getIndices();
  const vector<PositionMaterialNormal>& vecVertices = surfaceMesh.getVertices();

  for (int i=0; i<vecVertices.size(); i++)
  {
    float p[3], n[3], materialNo;
    p[0] = vecVertices[i].position.getX();
    p[1] = vecVertices[i].position.getY();
    p[2] = vecVertices[i].position.getZ();
    n[0] = vecVertices[i].normal.getX();
    n[1] = vecVertices[i].normal.getY();
    n[2] = vecVertices[i].normal.getZ();
    // float型
    materialNo = vecVertices[i].getMaterial();
  }

あと、テクスチャ座標は取得できない?ようでしたので、面と頂点座標情報から適当に生成して1面に1枚下記画像を張り付けるようにしてみました。
polyvox_test2_003.png

voxファイルにはマテリアル番号と対応する色パレットがありますので、色×テクスチャ色で適当に色付けしています。

実行結果
biome.voxを使用させていただいております。問題があればお知らせください。

 polyvox_test2_001.png polyvox_test2_002.png

まぁMagicaVoxelでPlyやObjで出力できますので、MagicaVoxel対応データをポリゴン化する意味はないですが、現状ではサイズ制限がありますので、大きめのボリュームデータをとりあえずボクセル化したい場合などには使えるかなとは思います。

[1] http://www.volumesoffun.com/polyvox-about/
[2] https://ephtracy.github.io/
[3] http://www.volumesoffun.com/polyvox/documentation/0.2.1/manual/tutorial1.html
web拍手 by FC2
posted by シンドラー at 00:23 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする