01−04、polymesh3



表示用データを作る
01-03章でmqoのオブジェクトデータをCMQOObjectクラスに読み込みました。
OpenRDBではポリゴンは三角のみを扱います。
CMQOObjectのデータのままでは、表示データに四角が混ざっていますし
データの順序もマテリアルごとに分かれていません。

ですので表示データ用にCMQOObjectのデータを整形する必要があります。
それをするクラスがCPolyMesh3です。
CPolyMesh3の変数メンバを以下に示します。

class CPolyMesh3
{

    ...(関数メンバ省略)

public:
    int m_orgpointnum;
    int m_orgfacenum;
    int m_facenum;//三角分割後の面数

    float m_facet;
    CMQOFace* m_mqoface;//外部メモリ
    D3DXVECTOR3* m_pointbuf;//外部メモリ
    N3P* m_n3p;

    int m_optleng;
    int m_optmatnum;
    PM3DISPV* m_dispv;
    int* m_dispindex;
    int m_createoptflag;

    MATERIALBLOCK* m_matblock;
    MODELBOUND m_bound;

    CHKALPHA chkalpha;
};

m_orgpointnum, m_orgfacenumはCMQOObjectで読み込んだのと同じ頂点数と面の数です。
m_facenumは線分を排除し、四角は三角に分割した後の三角の総数です。

m_facetはメタセコイアで設定可能なスムージング角度です。
m_n3pは描画面数 × 3 の頂点データです。

m_optlengは最適化後の頂点数です。(このバージョンでは面数×3のままです)
m_optmatnumはオブジェクトで参照しているマテリアルの数です。
m_dispvは描画用の頂点データです。
m_dispindexは描画用のインデックスデータです。

m_matblockは描画データをマテリアルごとにまとめた後、どこからどこまでがどのマテリアルかを記録するものです。
m_boundは境界情報です。


スムージング

スムージングとは法線に対する処理の1つです。スムージングするとその部分が滑らかに丸みを帯びて表示されます。
スムージングしないと角ばった形状になります。

面同士の角度がm_facetより大さい角度のときにスムージングします。
この処理でかなりややこしい処理をしています。

現在のソースは2日くらいでスムージング処理を考えたもので
最善のものとは言いがたいです。
もっと処理速度の速い方法などを思いつきましたら教えてください。

簡単にスムージング手順の説明をします。

まずソースに出てくる構造体を示します。これらの構造体はcoef.hに書かれています。

typedef struct tag_verface
{
    int faceno;
    int orgfaceno;
    int materialno;
    D3DXVECTOR3 facenormal;
}PERFACE;

typedef struct tag_pervert
{
    int indexno;//3角の順番
    int vno;
    int uvnum;
    D3DXVECTOR2 uv[2];
    int vcolflag;
    DWORD vcol;
    D3DXVECTOR3 smnormal;

    int createflag;
    //頂点を作成しない場合0
    //UV, VCOL, Materialnoの違いにより作成する場合は1を足す
    //normalにより作成する場合は2を足す
}PERVERT;

typedef struct tag_n3sm
{
    int smfacenum;
    void** ppsmface;//N3Pのポインタの配列
}N3SM;

typedef struct tag_n3p
{
    PERFACE* perface;
    PERVERT* pervert;
    N3SM* n3sm;
}N3P;//n*3

typedef struct tag_pm3dispv
{
    D3DXVECTOR4 pos;
    D3DXVECTOR3 normal;
    D3DXVECTOR2 uv;
}PM3DISPV;

PERVERTは頂点に固有のデータ、PERFACEは面に固有のデータを示します。
N3SMは法線を平均化する面の情報を示します。
N3Pは全ての頂点のデータを格納します。
PM3DISPVは描画用の頂点のデータを格納します。

手順は
1、n3pをvno, materialno, uv, vcolでソートします。
2、n3pを頭からチェックし、まったく同じものが無ければcreateflagに1を足す。
3、n3でvnoが等しいものの法線をチェックしスムージングするものが見つかったらppsmfaceに追加する。
全部終わったら
4、n3pのvnoが等しいものの*ppsmfaceをチェックし、
自分が始めて出現したときまたは出現しなかったときかつcreateflagに2が足されていないとき
createflagに2を足す。
5、n3smからsmnormalを計算する。
6、n3pをmaterialno, faceno, indexnoでソートする。
7、n3pのcreateflagを見て0以外のものからPM3DISPVを作る。

という具合です。


01章のトップに戻る

オープンソースのトップに戻る

トップページに戻る