bambooflow Note

Xファイル

最終更新:

Bot(ページ名リンク)

- view
メンバー限定 登録/ログイン

ODEでXファイルからポリゴンを表示する



Xファイルは、DirectXの3Dフォーマットのようです。
多くの3Dモデリングツールがサポートしています。
たとえば、BlenderやMetasequoiaといったもの。

ここでは、Xファイル(アスキー形式)を読み込むためのクラスを作ってみました。
デバッグはそこそこしかしてません。
バグったらごめんなさい。

とりあえず、BleanderとMetasequoiaのXファイルは読めました。

BlenderでXファイルのエクスポート時、"Flip z"が有効になっているとポリゴンの表裏が反転してしまうので注意してください。



Metasequoia(無料版)の基本図形の1つ(立方体)を読み込んで表示したところ。
2つ生成して重ねています。

draw_x.zip

以前作成したSTL用のものとAPIを合わせて作っています。


使い方


  • ヘッダ
#include "XReader.h"

namespaceは、ode_utilsです。(using namespace ode_utils;)

  • クラス
ode_util::XReader<V_TYPE,IDX_TYPE>
V_TYPEは、頂点座標の型(floatもしくはdouble)
IDX_TYPEは、頂点座標番号の型(intもしくはdTriIndex)

  • API

XReader( const char* file_name ) コンストラクタ、file_nameは、読み込むX(アスキー)ファイル名
bool isCompleted() Xファイルが正常に読み込まれるとtrueを返す
const char* message() ファイル処理時の完了/エラーメッセージを返す
const vertex_type* getVertices() 頂点座標配列の先頭ポインタを返す
const index_type* getIndices() 頂点座標番号配列の先頭ポインタを返す
int getVertexCount() 頂点座標の数を返す。
int getIndexCount() 頂点座標番号の数を返す。

vertex_typeはV_TYPEで与えたもの。
index_typeはODX_TYPEで与えたもの。


  • XReaderの仕様

Xファイル内で、
Mesh {
 ・・・
}
のvertex数、頂点データ、index数、頂点インデックスのみを取得します。
template{}はすべて無視します。
MeshMaterialList、Material、Normalといったものもすべて無視です。

頂点インデックスは、3つ(三角形)もくしは4つ(四角形)の番号がセットになる場合があります。ODEのTriMeshは4つには対応していないので、4つセットのものは3つに分割しています。


字句解析には、無駄にre2cを使っています。(勉強がてら)
なのでクラスの中は一部人には読めないものになっています。


ODE記述


#include "XReader.h"

static dBodyID body1, body2;
static dGeomID geom1, geom2; 
ode_utils::XReader<float,dTriIndex> *mesh;
 
 
    mesh = new ode_utils::XReader<float,dTriIndex>("cube2.x");
    if (!mesh->isCompleted()) {
        printf( "mesh error\n");
        printf( "msg : \n%s", mesh->message() );
 
        printf("vertexCount=%d\n", mesh->getVertexCount());
        printf("getIndexCount=%d\n", mesh->getIndexCount());
        printf("vertices pointer=%d\n", mesh->getVertices());
        printf("indices pointer=%d\n", mesh->getIndices());
        exit(1);
    }
 
 
    body = dBodyCreate( world );
 
    dTriMeshDataID data;
    data = dGeomTriMeshDataCreate();
    dGeomTriMeshDataBuildSingle(data, mesh->getVertices(), 3*sizeof(float), mesh->getVertexCount(),
        mesh->getIndices(), mesh->getIndexCount(), 3*sizeof(dTriIndex));
 
    geom = dCreateTriMesh(space, data, 0, 0, 0);
    dGeomSetData( geom, data );
 
    dMass m;
    dMassSetTrimesh( &m, mass, geom );
    dGeomSetPosition( geom, -m.c[0], -m.c[1], -m.c[2] );
    dMassTranslate( &m, -m.c[0], -m.c[1], -m.c[2] );
    dBodySetMass( body, &m );
 
    dGeomSetBody( geom, body );
 
 


drawstuff記述例


dsSetColor( 1, 1, 0 );
    {
        const dReal* pos = dGeomGetPosition(geom1);
        const dReal* rot = dGeomGetRotation(geom1);
 
        const dTriIndex *index = mesh->getIndices();
        for (int ii = 0; ii < mesh->getIndexCount()/3; ii++) {
            const dReal v[9] = {
                mesh->getVertices()[index[ii*3+0]*3 + 0],
                mesh->getVertices()[index[ii*3+0]*3 + 1],
                mesh->getVertices()[index[ii*3+0]*3 + 2],
                mesh->getVertices()[index[ii*3+1]*3 + 0],
                mesh->getVertices()[index[ii*3+1]*3 + 1],
                mesh->getVertices()[index[ii*3+1]*3 + 2],
                mesh->getVertices()[index[ii*3+2]*3 + 0],
                mesh->getVertices()[index[ii*3+2]*3 + 1],
                mesh->getVertices()[index[ii*3+2]*3 + 2]
            };
            dsDrawTriangle( pos, rot, &v[0], &v[3], &v[6], 1 );
        }
    }
 
添付ファイル
記事メニュー
ウィキ募集バナー