トップ | puarts.com
メモ  |  制作記  |  開発記  |  日常の記録  |  デジタルコンテンツ制作  |  ファイアーエムブレム  |  ゲーム  |  C/C++  |  C#  |  PC/ソフトウェア  |  Web 開発  |  スクリプト言語  |  その他プログラミング  |  
「3DCG」に関連する記事一覧

0  1  2  3  

キューブマップと正距円筒画像を相互変換可能な 360 TOOL KIT

キューブマップの分解と結合を行えるフリーソフトないかなぁと探してたところ、正距円筒(Equirectangular)画像からキューブマップへの変換、キューブマップからの正距円筒画像への変換ができる 360 TOOL KIT という便利なオンラインサービスがありましたので、メモしておきます。

Unity で作った木のモデルを fbx エクスポート

Unity で作った木のモデルデータを fbx にエクスポートして外部で使用する方法をメモしておきます。

fbxsdk でアニメーション関連の機能を使ったらリンクエラー

2017/11/26

昔作っていたモデル描画プログラムで fbx ファイルからアニメーション読み込み対応しようと、FBXSDK のアニメーション機能を使ってみたところ、以下のリンクエラーが発生しました。


error LNK2001: 外部シンボル ""public: static class fbxsdk::FbxClassId fbxsdk::FbxAnimStack::ClassId" (?ClassId@FbxAnimStack@fbxsdk@@2VFbxClassId@2@A)" は未解決です。
error LNK2001: 外部シンボル ""class fbxsdk::FbxDataType fbxsdk::FbxColor3DT" (?FbxColor3DT@fbxsdk@@3VFbxDataType@1@A)" は未解決です。
error LNK2001: 外部シンボル ""class fbxsdk::FbxDataType fbxsdk::FbxColor4DT" (?FbxColor4DT@fbxsdk@@3VFbxDataType@1@A)" は未解決です。
error LNK2001: 外部シンボル ""private: static void (__cdecl* fbxsdk::FbxAnimCurveKey::mDeallocatorFct)(class fbxsdk::FbxAnimCurveKey_Impl *)" (?mDeallocatorFct@FbxAnimCurveKey@fbxsdk@@0P6AXPEAVFbxAnimCurveKey_Impl@2@@ZEA)" は未解決です。
error LNK2001: 外部シンボル ""public: static class fbxsdk::FbxClassId fbxsdk::FbxAnimLayer::ClassId" (?ClassId@FbxAnimLayer@fbxsdk@@2VFbxClassId@2@A)" は未解決です。

これまで頂点データの読み込み等は問題なく行えていたので、なぜアニメーション関連の機能だけリンクエラーになるんだろうと思って、ネットで調べたところ、Autodesk のフォーラムで同じ問題にはまっている人がいました。

https://forums.autodesk.com/t5/fbx-forum/cannot-find-static-symbol/td-p/5816698

こちらのフォーラムにあるように私も libfbxsdk.lib をリンクしていたのですが、これではなく libfbxsdk-md.lib の方をリンクしたらビルドが通るようになりました。FBXSDK のライブラリディレクトリには fbxsdk.lib、fbxsdk-mt.lib、fbxsdk-md.lib の3つがありますが、mt と md は意味はわかるのですが、無印のは何用なんでしょうか。アニメーション機能を利用するまでは libfbxsdk.lib でもちゃんとビルド通るし、この lib の役割がよくわからないですね。

FBX SDK スキニングしているジョイントのローカル座標、変換行列取得

2017/04/16

FBX SDK を使って fbx からスキニングしているジョイントのローカル座標を取得する方法がヘルプ読まずにわからなかったので、メモ代わりにスキニングしているジョイントのローカル座標と変換行列をコンソール出力する関数を載せておきます。

ソースコード


void PrintLocalSrtAndTransformMatrixOfJoints(FbxNode* root_node)
{
    FbxMesh* mesh = root_node->GetMesh();
    int skin_count = mesh->GetDeformerCount(FbxDeformer::eSkin);
    for (int skin_index = 0; skin_index < skin_count; ++skin_index)
    {
        FbxSkin* skin = static_cast<FbxSkin*>(mesh->GetDeformer(skin_index, FbxDeformer::eSkin));
        int cluster_count = skin->GetClusterCount();
        for (int cluster_index = 0; cluster_index < cluster_count; ++cluster_index)
        {
            FbxCluster* cluster = skin->GetCluster(cluster_index);
            FbxNode* linked_node = cluster->GetLink();
            printf("%s:\n", linked_node->GetName());

            // ジョイントのローカル SRT を表示
            fbxsdk::FbxDouble3 local_translate = linked_node->LclTranslation.Get();
            fbxsdk::FbxDouble3 local_rotate = linked_node->LclRotation.Get();
            fbxsdk::FbxDouble3 local_scale = linked_node->LclScaling.Get();
            printf("    t = (%8.3f, %8.3f, %8.3f)\n    r = (%8.3f, %8.3f, %8.3f)\n    s = (%8.3f, %8.3f, %8.3f)\n",
                local_translate[0],
                local_translate[1],
                local_translate[2],
                local_rotate[0],
                local_rotate[1],
                local_rotate[2],
                local_scale[0],
                local_scale[1],
                local_scale[2]);

            // ジョイントの変換行列を表示
            fbxsdk::FbxAMatrix init_matrix;
            cluster->GetTransformLinkMatrix(init_matrix);
            printf("    matrix =\n");
            for (int row = 0; row < 4; ++row)
            {
                printf("        ");
                for (int col = 0; col < 4; ++col)
                {
                    printf("%8.3f, ", init_matrix.Get(row, col));
                }
                printf("\n");
            }
        }
    }
}

コンソール出力結果例

joint1:
    t = (   0.000,    0.000,    0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    0.000,    0.000,    1.000,
joint2:
    t = (   0.000,    1.000,    0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    1.000,    0.000,    1.000,
joint3:
    t = (   0.000,    1.000,   -0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    2.000,   -0.000,    1.000,
joint4:
    t = (   1.000,    1.000,   -0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           1.000,    3.000,   -0.000,    1.000,

ついでにサンプルにあったバインドポーズのトンラスフォームの取得方法もメモ代わりに載せておきます。

バインドポーズのトランスフォームと行列(サンプルより)


void DisplayPose(FbxScene* pScene)
{
    int      i, j, k, lPoseCount;
    FbxString  lName;

    lPoseCount = pScene->GetPoseCount();

    for (i = 0; i < lPoseCount; i++)
    {
        FbxPose* lPose = pScene->GetPose(i);

        lName = lPose->GetName();
        printf("Pose Name: %s\n", lName.Buffer());

        printf("    Is a bind pose: %s\n", lPose->IsBindPose()?"true":"false");

        printf("    Number of items in the pose: %d\n", lPose->GetCount());

        printf("\n");

        for (j = 0; j<lPose->GetCount(); j++)
        {
            lName = lPose->GetNodeName(j).GetCurrentName();
            printf("    Item name: %s\n", lName.Buffer());

            if (!lPose->IsBindPose())
            {
                // Rest pose can have local matrix
                printf("    Is local space matrix: %s\n", lPose->IsLocalMatrix(j)?"true":"false");
            }

            printf("    Matrix value: \n");

            FbxString lMatrixValue;

            FbxNode* node = lPose->GetNode(j);

            for (k = 0; k<4; k++)
            {
                FbxMatrix  lMatrix = lPose->GetMatrix(j);
                FbxVector4 lRow = lMatrix.GetRow(k);
                char        lRowValue[1024];

                FBXSDK_sprintf(lRowValue, 1024, "%9.4f %9.4f %9.4f %9.4f\n", lRow[0], lRow[1], lRow[2], lRow[3]);
                lMatrixValue += FbxString("        ") + FbxString(lRowValue);
            }

            printf("%s\n", lMatrixValue.Buffer());
        }
    }

    lPoseCount = pScene->GetCharacterPoseCount();

    for (i = 0; i < lPoseCount; i++)
    {
        FbxCharacterPose* lPose = pScene->GetCharacterPose(i);
        FbxCharacter*     lCharacter = lPose->GetCharacter();

        if (!lCharacter) break;

        printf("Character Pose Name: %s\n", lCharacter->GetName());

        FbxCharacterLink lCharacterLink;
        FbxCharacter::ENodeId  lNodeId = FbxCharacter::eHips;

        while (lCharacter->GetCharacterLink(lNodeId, &lCharacterLink))
        {
            FbxAMatrix& lGlobalPosition = lCharacterLink.mNode->EvaluateGlobalTransform(FBXSDK_TIME_ZERO);

            printf("    Matrix value: %s\n", "");

            FbxString lMatrixValue;

            for (k = 0; k<4; k++)
            {
                FbxVector4 lRow = lGlobalPosition.GetRow(k);
                char        lRowValue[1024];

                FBXSDK_sprintf(lRowValue, 1024, "%9.4f %9.4f %9.4f %9.4f\n", lRow[0], lRow[1], lRow[2], lRow[3]);
                lMatrixValue += FbxString("        ") + FbxString(lRowValue);
            }

            printf("%s\n", lMatrixValue.Buffer());

            lNodeId = FbxCharacter::ENodeId(int(lNodeId) + 1);
        }
    }
}

MeshLab で .stl ファイルを .obj ファイルなどに変換する

襖 CG

2016/07/03 09:35

建物のプロジェクションマッピング映像で襖絵を使った演出は汎用的に使えそうだったので、襖絵っぽい絵を Photoshop で描いて、襖の 3DCG モデル作って貼り付けてみました。

襖のアニメーションは閉じたり開いたりするのだけ作っておけば、あとはテクスチャ差し替えで色々なバリエーション作れるので、プロジェクションマッピング映像の演出の中に組み込みやすそうです。

行優先行列、列優先行列

2015/11/17

行列演算をしていて、行優先(Row-major)と列優先(Column-major)で混乱してしまったので、整理するために情報を探していたらいいページを見つけましたので貼っておきます。

http://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/row-major-vs-column-major-vector

Maya は Row-major で、OpenGL は Column-major であることをたまに忘れるので、こういう表があると助かります。

マウスの軌跡をパーティクルで描くテスト

2015/07/26 20:00

マウスでパーティクルの発生を制御し、マウスの軌跡に沿ってパーティクルが発生するプログラムを作りました。

3D 空間を覆う球体と視点座標の Z 軸の交点をパーティクルの発生座標としています。

球体の真上と真下に行ってしまうと、視点の上下が簡単にひっくり返ってぐるぐる回ってしまう問題があったところが、少しはまりました。これは、Y 座標は一定の座標を超えないように閾値を設けたところ、いい感じの操作感にすることができました。

角度が合うと文字に見えるパーティクル表現

2015/07/26 10:00

ある角度から見ると文字に見えるようなパーティクル表現のテストです。

やったことを書いておきます。

  1. 液タブであるカメラの位置から文字を書く
    1. マウスドラッグのXY座標、Zはランダムな座標を視点座標として定義
    2. そこにビュー行列の逆行列を乗算してワールド座標を取得
    3. その座標にパーティクルを生成
  2. カメラの角度を適当にずらす(動画の最初の状態)
  3. カメラの角度を文字を書いた時の角度に戻す(動画で文字に見えた状態)

セルオートマトンを応用した文字エフェクト

2015/07/20

以前作ったセルオートマトンによる水滴表現プログラムを応用して、文字エフェクトツールを作りました。

液タブで文字を書くとこんな感じになります。やっぱり直接画面に書けるのは楽しいです。

このツールで作った映像はイメージシーケンスでレンダリング結果を保存できるようにしたので、After Effectsとかに持っていけば映像制作の素材としても使えるようになってます。いつか、ちゃんとしたツールにしたい...

簡単に中身で何をやっているか書いておきます。

  1. マウスドラッグした地点にパーティクルを発生させる
  2. パーティクルが発生することにより、発生箇所のピクセルがRGB(0, 0, 0)でない色情報を持つ
  3. RGB(0, 0, 0)であるピクセルは、RGB(0, 0, 0)でないピクセルに影響を与え、逆にRGB(0, 0, 0)でないピクセルはRGB(0, 0, 0)であるピクセルにも影響を与える。これにより、すべてのピクセルは隣接ピクセルの状態により生成と消滅を繰り返す

0  1  2  3  

にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

0.022 sec

Copyright(C)2006-2018 wsp All Rights Reserved