ODEでSTLフォーマット(3D)の物体を作る方法について
3D形状フォーマットにSTLというのがあるみたいです。
それを読み込んでODE上に生成する方法をメモします。
それを読み込んでODE上に生成する方法をメモします。
STLはアスキーとバイナリの2種類あるようですが、ここではバイナリのみについてです。
STLは三角形メッシュソリッドなので、ODEのAPITriMesh*で簡単に扱えます。
STLは三角形メッシュソリッドなので、ODEのAPITriMesh*で簡単に扱えます。
とりあえず、STL(バイナリ)フォーマットファイルを読み込むクラスを作ってみました。
ODE記述は、demo_moving_trimesh.cppを参考にしました。
- サンプル(試しにBlenderのMonkeyを描画)


STL読み込みクラス
あんまりデバッグしてません。バグったらごめんなさい。
- ヘッダ
#include "StlReader.h"
namespaceは、ode_utilsです。(using namespace ode_utils;)
- クラス
ode_util::StlReader<V_TYPE,IDX_TYPE>
V_TYPEは、頂点座標の型(floatもしくはdouble)
IDX_TYPEは、頂点座標番号の型(intもしくはdTriIndex)
IDX_TYPEは、頂点座標番号の型(intもしくはdTriIndex)
- API
StlReader( const char* file_name ) | コンストラクタ ()file_nameは、読み込むSTL(バイナリ)ファイル名 |
bool isCompleted() | 処理が正しく行われるとtrueを返す |
const char* message() | STLファイル処理の正常/エラーメッセージを返す |
const vertex_type* getVertices() | 頂点座標配列の先頭ポインタを返す |
const index_type* getIndices() | 頂点座標番号配列の先頭ポインタを返す |
int getVertexCount() | 頂点座標の数を返す。 |
int getIndexCount() | 頂点座標番号の数を返す。 |
vertex_typeはV_TYPEで与えたもの。
index_typeはODX_TYPEで与えたもの。
index_typeはODX_TYPEで与えたもの。
ODE記述
ode_util::StlReader<float,dTriIndex> *stl;
static dBodyID body;
static dGeomID geom;
void createMonkey( dWorldID world, dSpaceID space, dReal mass)
{
stl = new ode_util::StlReader<float,dTriIndex>("monkey_binary.stl");
body = dBodyCreate( world );
dTriMeshDataID data;
data = dGeomTriMeshDataCreate();
dGeomTriMeshDataBuildSingle(data, stl->getVertices(), 3*sizeof(float), stl->getVertexCount(),
stl->getIndices(), stl->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描画
{
const dReal* pos = dGeomGetPosition(geom);
const dReal* rot = dGeomGetRotation(geom);
for (int ii = 0; ii < stl->getIndexCount()/3; ii++) {
const dReal v[9] = {
stl->getVertices()[stl->getIndices()[ii*3+0]*3 + 0],
stl->getVertices()[stl->getIndices()[ii*3+0]*3 + 1],
stl->getVertices()[stl->getIndices()[ii*3+0]*3 + 2],
stl->getVertices()[stl->getIndices()[ii*3+1]*3 + 0],
stl->getVertices()[stl->getIndices()[ii*3+1]*3 + 1],
stl->getVertices()[stl->getIndices()[ii*3+1]*3 + 2],
stl->getVertices()[stl->getIndices()[ii*3+2]*3 + 0],
stl->getVertices()[stl->getIndices()[ii*3+2]*3 + 1],
stl->getVertices()[stl->getIndices()[ii*3+2]*3 + 2]
};
dsDrawTriangle( pos, rot, &v[0], &v[3], &v[6], 1 );
}
}
参考
- http://www.hiramine.com/programming/3dmodelfileformat/stlfileformat.html