ODE講座22ODEでポリゎンを簡単に衚瀺する方法

2007-11-01
By

ODE texture

Archive3D.netからダりンロヌドした3DSフォヌマットの「うさちゃん」。lib3dsラむブラリを䜿うこずでODE付属のdrawstuffで衚瀺できたした。

早いものでもう月ですね。卒業研究や修士研究に取り組んでいる方はお尻に火か着くころではないでしょうか。

さお、ODE (Open Dynamics Engine講座の22回目です。ODEに付属しおいる次元グラフィクスラむブラリdrawstuffではDモデルのファむルを読み蟌みたせん。ひびきのさんはXファむルあの謎が謎を呌ぶTV番組ではありたせん。最も最近はPrison Breakに倢䞭ですが…を読み蟌むX File Loaderを公開しおいたす。 ここではもう䞀぀の暙準的な3Dファむルである3DSを読み蟌むサンプルプログラムをテスト公開したす。

3dsファむルを読み蟌むラむブラリずしおlib3dsを䜿いたす。これはJan Eric Kyprianidisさんが開発したものでLGPLで公開されおいたす。lib3dsのりェブサむトはここです。

たず、lib3dsをむンストヌルしたしょう。方法はODEず同じで 以䞋の芁領です。MSYS+MinGW+Windows Vista環境で問題なくできたした。

  • ./configure
  • make
  • make install

埌は、このode3dsloader-0.0.tgzファむルを次のリンクからダりンロヌドしお、

今たでのサンプルプログラムず同じように展開し、make、実行しおください。ただし、このプログラムは完党ではなく、耇数の郚品で構成されるモデルを衚瀺しようずするず゚ラヌになりたす。たた、テクスチャも衚瀺できたせん。そのためにはdrawstuffの゜ヌスを倉曎しなければなりたせん。今埌の宿題ずしたす。

なお、3dsファむルを衚瀺するためには、そのファむルが必芁になりたす。䞊図のうさちゃんはArchive3D.netのここからダりンロヌドしたした。

以䞋に゜ヌスコヌドの䞻芁郚分を掲茉したす。3dsファむルを読み蟌む関数がload3dsModel()です。読み蟌みが終わるず頂点配列Vertices[]ずむンデックス配列Indices[]にデヌタが栌玍されるので、埌はODE付属のdemoプログラムdemo_moving_trimesh.cppず同じようにプログラムするずポリゎンデヌタを扱うこずができたす。

぀たり、䞀般ナヌザはload3dsModel()を䞀行入れるだけで3dsファむルを読み蟌むこずができたす。簡単ですね。

ただ、テスト公開䞭で䞍完党です。耇数のオブゞェクトで構成される3dsデヌタを衚瀺できなければなりたせん。コメント頂ければありがたいです。


[code]
// main.cppから抜粋 by Kosei Demura 2007-11-1
//
#include
#include
#include "ode3dsloader.h"
extern int MeshCount; // オブゞェクト数

void makeModel()
{
static dReal weight = 10.0;
dReal x0 = 0, y0 = 0, z0 = 1.0;
dMass m;

// 3dsファむルをロヌドする関数。匕数は3dsファむル名
load3dsModel("../models/rabbit.3DS");

TriData = (dTriMeshDataID *) malloc(MeshCount * sizeof(dTriMeshDataID));

model = (MyObject *) malloc (MeshCount * sizeof(MyObject));

for (int i = 0; i < MeshCount; i++) {
// rigid body
model[i].body = dBodyCreate(world);
dBodySetPosition(model[i].body, x0, y0, z0);

// for a trimesh object
TriData[i] = dGeomTriMeshDataCreate();

dGeomTriMeshDataBuildSingle(TriData[i], trimesh[i].vertices, 3 * sizeof(float), trimesh[i].vertexCount, trimesh[i].indices, trimesh[i].indexCount * 3, 3 * sizeof(int));

model[i].geom = dCreateTriMesh(space, TriData[i], 0, 0, 0);

// remember the mesh’s dTriMeshDataID on its userdata for convenience.
dGeomSetData(model[i].geom, TriData[i]);

dMassSetTrimeshTotal(&m, weight, model[i].geom);
dGeomSetPosition(model[i].geom, -m.c[0], -m.c[1], -m.c[2]);
dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]);

dGeomSetBody(model[i].geom, model[i].body);
dBodySetMass(model[i].body, &m);

dMatrix3 Rotation;
dRFromAxisAndAngle(Rotation, 0, 0, 1, -M_PI/4);
dBodySetRotation(model[i].body, Rotation);
}
}

[/code]

[code]
// ode3dsloader.cpp by Kosei Demura 2007-11-01
// 3dsフォヌマットで䜜られたオブゞェクトを読み蟌むプログラム
// このファむルでload3dsModel()関数を実装しおいる。
// Todo぀の3Dモデルが耇数のオブゞェクトで構成されおいるず゚ラヌになる。
// lib3dsラむブラリが必芁http://lib3ds.sourceforge.net/
#include "ode3dsloader.h"
#define BASE_LENGTH 1.0 // メッシュモデルのバりンディングボックスの最倧長さ[m]
#define MAX_OBJECTS 1000 // オブゞェクトの数

typedef struct
{
float *vertices;
unsigned int vertexCount;
int *indices;
unsigned int indexCount;
} MyTrimesh;

extern MyTrimesh *trimesh;

dReal MIN_X = dInfinity, MAX_X = - dInfinity;
dReal MIN_Y = dInfinity, MAX_Y = - dInfinity;
dReal MIN_Z = dInfinity, MAX_Z = - dInfinity;
dReal ADJUST;
Lib3dsFile *file=0;

int MeshCount = 0;

int vCount[MAX_OBJECTS], iCount[MAX_OBJECTS];

void calModel(Lib3dsMesh *mesh, int *points, int *faces)
{
*points = mesh->points;
*faces = mesh->faces;
}

int meshDump(int no, Lib3dsMesh *mesh)
{
if (mesh->points == 0) return 0;

for (int i=0; i< (int) mesh->points; i++) {
trimesh[no].vertices[3*i] = mesh->pointL[i].pos[0];
trimesh[no].vertices[3*i+1] = mesh->pointL[i].pos[1];
trimesh[no].vertices[3*i+2] = mesh->pointL[i].pos[2];
if (MIN_X > mesh->pointL[i].pos[0]) MIN_X = mesh->pointL[i].pos[0];
if (MIN_Y > mesh->pointL[i].pos[1]) MIN_Y = mesh->pointL[i].pos[1];
if (MIN_Z > mesh->pointL[i].pos[2]) MIN_Z = mesh->pointL[i].pos[2];
if (MAX_X < mesh->pointL[i].pos[0]) MAX_X = mesh->pointL[i].pos[0];
if (MAX_Y < mesh->pointL[i].pos[1]) MAX_Y = mesh->pointL[i].pos[1];
if (MAX_Z < mesh->pointL[i].pos[2]) MAX_Z = mesh->pointL[i].pos[2];
}

for (int i=0; i< (int) mesh->faces; i++) {
trimesh[no].indices[3*i] = mesh->faceL[i].points[0];
trimesh[no].indices[3*i+1] = mesh->faceL[i].points[1];
trimesh[no].indices[3*i+2] = mesh->faceL[i].points[2];
}
return 1;
}

// トラむメッシュデヌタのサむズ倉曎
int normalize(int no, Lib3dsMesh *mesh)
{
if (mesh->points == 0) return 0;

for (int i=0; i< (int) mesh->points; i++) {
trimesh[no].vertices[3*i]  *= (dReal) ADJUST;
trimesh[no].vertices[3*i+1] *= (dReal) ADJUST;
trimesh[no].vertices[3*i+2] *= (dReal) ADJUST;
}
return 1;
}

void load3dsModel(const char *filename)
{
int points, faces, no;
Lib3dsMesh *p;

file = lib3ds_file_load(filename);
if (!file) {
puts("3dsplayer: Error: Loading 3DS file failed.\n");
exit(1);
}

for (p=file->meshes; p!=0; p=p->next) {
calModel(p, &points, &faces);
if (points == 0) continue;
MeshCount++;
}

trimesh = (MyTrimesh *) malloc(MeshCount * sizeof(MyTrimesh));
no = 0;
for (p=file->meshes; p!=0; p=p->next) {
calModel(p, &points, &faces);
if (points == 0) continue;

vCount[no] = points;
iCount[no] = faces;
trimesh[no].vertices = (float *) malloc(vCount[no] * sizeof(float) * 3);
trimesh[no].indices = (int *) malloc(iCount[no] * sizeof(int) * 3);
trimesh[no].vertexCount = vCount[no];
trimesh[no].indexCount = iCount[no];
no++;
}

no = 0;
for (p=file->meshes; p!=0; p=p->next) {
if (meshDump(no, p)) no++;
}

dReal maxLength;

if (MAX_X - MIN_X >= MAX_Y - MIN_Y) {
if (MAX_X - MIN_X >= MAX_Z - MIN_Z) maxLength = MAX_X - MIN_X;
else maxLength = MAX_Z - MIN_Z;
}
else {
if (MAX_Y - MIN_Y >= MAX_Z - MIN_Z) maxLength = MAX_Y - MIN_Y;
else maxLength = MAX_Z - MIN_Z;
}

ADJUST = BASE_LENGTH / maxLength;

no = 0;
for (p=file->meshes; p!=0; p=p->next) {
if (normalize(no, p)) no++;
}
}
[/code]

[code]
// ode3dsloader.h

#include
#include
// for lib3ds
#include #include #include #include #include #include #include #include #include

void load3dsModel(const char *filename);

[/code]


続く…


20 Responses to ODE講座22ODEでポリゎンを簡単に衚瀺する方法

  1. demu MonsterID Icon demu on 2008-05-09

    koboさん

    テストしたいのでうさぎの3dsファむルを私に送っお頂けたせんか
    メヌルアドレスはProfileカテゎリにありたす

    でむ

  2. demu MonsterID Icon demu on 2008-05-04

    koboさん

    コメントありがずうございたす
    珟圚ロボカップゞャパンオヌプンで取り蟌んでいたす回答はゎヌルりィヌク明けになるず思いたす

    すみたせん

    でむ

  3. kobo MonsterID Icon kobo on 2008-05-03

    本を買い、非垞に興味深く、勉匷させお頂いおおりたす。
    3DSのファむルを読みんで衚瀺させようずしおおりたすが、うたくいきたせん。
    lib3dsのラむブラリを䜿おうずしおいたす。
    ラむブラリの組み蟌みや、サンプルのプログラムはうたくいったのですが、
    公開されおいるode3dsloader-0.0.tgzファむルだず、うさぎが読み蟌めたせん。
    どこがおかしいのか教えお頂けないでしょうか

    症状ずしおは、

    ode3dsloader.cpp の以䞋の堎所で

    84行目
    for (p=file->meshes; p!=0; p=p->next) {
    calModel(p, &points, &faces);
    if (points == 0) continue;
    MeshCount++;
    }

    file->meshesが0になり、MeshCountのカりントアップが0で
    進んでいないようです。

    ファむルの読み蟌みは、
    puts(“3dsplayer: Error: Loading 3DS file failed.\n”);
    にはならないので、読み蟌めおいるず思われたす。

    ご指導頂ければ幞いです。

  4. ミルトン MonsterID Icon ミルトン on 2007-11-16

    lib3ds-examples.tgzを詊しおみたしたが䞋蚘のずおりずなっおしたいたした。msysのトップからのディレクトリ構成ず䞻芁ラむブラリのメモ曞きがあったらメヌルに添付しおいただけたすでしょうか?

    $ make
    g++ -Wall -fno-exceptions -fno-rtti -g -DWIN32 -c 3dsplay.c -L/lib -L/usr/lib -L../lib -L../../drawstuff/src -L/usr/local/lib -I/include -I/usr/include -I../include -I. -I../../include -I/usr/local/include
    In file included from ../../include/lib3ds/types.h:51,
    from ../../include/lib3ds/background.h:27,
    from ../../include/lib3ds/file.h:27,
    from 3dsplay.c:27:
    ../include/stdint.h:24:20: stddef.h: No such file or directory
    In file included from ../../include/lib3ds/types.h:78,
    from ../../include/lib3ds/background.h:27,
    from ../../include/lib3ds/file.h:27,
    from 3dsplay.c:27:
    ../include/stdio.h:28:20: stdarg.h: No such file or directory
    In file included from ../../include/lib3ds/types.h:78,
    from ../../include/lib3ds/background.h:27,
    from ../../include/lib3ds/file.h:27,
    from 3dsplay.c:27:
    ../include/stdio.h:191: error: `size_t’ has not been declared
    ../include/stdio.h:191: error: ISO C++ forbids declaration of `parameter’ with no type
    ../include/stdio.h:202: error: `size_t’ has not been declared

  5. でむ MonsterID Icon でむ on 2007-11-16

    ミルトンさん、

    ディレクトリ構成党䜓ずは、msysのトップディレクトリからですか それでも/home/ナヌザ名/src/ode-0.9からでしょうか

    でむ

  6. でむ MonsterID Icon でむ on 2007-11-16

    ミルトンさん、

    3dsplay.cはそのたたでぱラヌになるので、゜ヌスを倉曎する必芁がありたす。C蚀語の゜ヌスコヌドをg++ずいうC++のコンパむラヌでコンパむルしおいるのも原因の䞀぀ですが、gccでコンパむルしおも゚ラヌは残りたす。

    これは、demura.netのサンプルプログラムをVisual C++でもコンパむルできるようにするためです。C++の方がCより型チェックが厳しいですから。

    なお、コンパむルできるようにしたファむル䞀匏をたずめお以䞋に眮きたしたのでゲットしおください。makeしおください。http://demura.net/archives/images/ode/lib3ds-examples.tgz

    でむ

  7. ミルトン MonsterID Icon ミルトン on 2007-11-16

    おそれいりたすが、ディレクトリ構成党䜓をワヌドなどに貌り付けお送っおいただけたすでしょうか?
    最初から確認しなおしたす。

  8. ミルトン MonsterID Icon ミルトン on 2007-11-15

    ラむブラリの䜍眮が原因なのかincludeの䜍眮が悪いのかず思い、makeで指定しおいるフォルダのファむルを自分のディレクトリにコピヌしたりしお様子を芋おいたすが、䞻だった成果が埗られおいたせん。
    自分のディレクトリずいうのは/msys/1.0/home/username/src/ode-0.9/mytestここです。

    環境自䜓がめちゃくちゃになっおいたず思い、MinGW,Msysをマニュアルで解凍、展開、make installしなおしたした。腑に萜ちないのが、MinGW,Msysをdownloadするずきに同時にダりンロヌドされる圧瞮ファむルをむンストヌルしたほうがよいのかず思い、むンストヌルしたしたが内容は倉わらないようでした。問題ないずおもいたした。

    コメントいただければおねがいしたす。

  9. ミルトン MonsterID Icon ミルトン on 2007-11-15

    修正したのですが3dsplay.exeはただできおいたせん。ode3rdloader rabbit.3dsも動きたせん
    恐れ入りたすが、コメントいただきたく。

    $make

    $ g++ -Wall -fno-exceptions -fno-rtti -g -DWIN32 -c 3dsplay.c -L/lib -L/usr/li
    b -L../lib -L../../drawstuff/src -L/usr/local/lib -I/include -I/usr/include -I

    ../include -I. -I../../include -I/usr/local/include
    3dsplay.c: In function `void toggle_bool(int, int, void*)’:
    3dsplay.c:178: error: invalid conversion from `void*’ to `int*’
    3dsplay.c: In function `void render_node(Lib3dsNode*)’:
    3dsplay.c:479: error: invalid conversion from `void*’ to `float (*)[3]‘
    3dsplay.c:515: error: invalid conversion from `void*’ to `Player_texture*’
    3dsplay.c:540: warning: unused variable ‘upload_format’
    3dsplay.c: In function `void display()’:
    3dsplay.c:790: error: expected unqualified-id before ‘,’ token
    3dsplay.c:790: error: expected unqualified-id before ‘,’ token
    3dsplay.c:834: error: expected primary-expression before ‘=’ token
    3dsplay.c:835: error: expected primary-expression before ‘=’ token
    3dsplay.c:858: error: expected primary-expression before ‘<=’ token
    3dsplay.c:858: error: expected primary-expression before ‘=’ token
    3dsplay.c:858: error: invalid type argument of `unary *’
    3dsplay.c:860: error: expected primary-expression before ‘,’ token
    3dsplay.c:860: error: expected primary-expression before ‘)’ token
    3dsplay.c: In function `void create_icons()’:

  10. でむ MonsterID Icon でむ on 2007-11-14

    ミルトンさん、

    セパレヌタ゚ラヌはmakefileの䞭でTABが入っおいないからです。
    TABずいうのはキヌボヌドのTABキヌのこずです。
    私も初めおこの゚ラヌに出䌚ったずきは意味䞍明でした。

    このりェブサむトの性質䞊で、カットアンドペヌストでTABをコピヌできないので゚ラヌになりたす。
    以前のコメントのmakefileでTABをいれる堎所に[TAB]ず曞きたしたのでコピヌしおからTABを入れおください。

    わからなければ、たた質問お願いしたす。

    でむ

  11. ミルトン MonsterID Icon ミルトン on 2007-11-14

    msys/1.0/home/username/src/lib3ds-1.3.0/example/3dsplay.c
    を掲茉のmake文で実行しようずmakefileずしおセヌブしお、msysでmakeしたら
    セパレヌタ゚ラヌが起こっおしたいたした。党角半角倉換は完了しおも再び䞋蚘の
    メッセヌゞがでたした。

    $ make
    makefile:14: *** missing separator. Stop.

  12. でむ MonsterID Icon でむ on 2007-11-14

    ミルトンさん、

    補足したす。

    3dsplay.cのコンパむルにはmakefileを䜿っおください。
    たた、3dsplay.cはglutを䜿っおいるのでglutをむンストヌルする必芁がありたす。

    glutのむンストヌル法は
    http://www-sens.sys.es.osaka-u.ac.jp/wakate/tutorial/group3/glui/glui3.html
    の蚘事のWindows XP, MinGWのgccが参考になりたす。

    # makefile
    CC = g++ -Wall -fno-exceptions -fno-rtti -g -DWIN32
    TARGET = 3dsplay
    OBJS = 3dsplay.o
    SOURCE = 3dsplay.c
    HEADER =
    WINDRES = windres
    LIBS = -L/lib -L/usr/lib -L../lib -L../../drawstuff/src -L/usr/local/lib
    INDS = -I/include -I/usr/include -I../include -I. -I../../include -I/usr/local/include
    OPTS = -lstdc++ -lcomctl32 -lkernel32 -luser32 -lgdi32 -lopengl32 -lglu32 -lglut32 -lwinmm -lm -l3ds

    $(TARGET):$(OBJS) $(RESOURCE_FILE) $(HEADER)
    [TAB] $(CC) -mwindows -o $@ $(OBJS) $(LIBS) $(INDS) $(OPTS)

    $(OBJS): $(SOURCE) $(HEADER)
    [TAB] $(CC) -c $(SOURCE) $(LIBS) $(INDS)

    clean:
    [TAB] rm $(TARGET) $(OBJS) *.*~ *~ *.exe *.*.stackdump

  13. でむ MonsterID Icon でむ on 2007-11-13

    ミルトンさん、

    頂いたrabbit.3DSをode3dsloader-0.0で実行したずころ問題なくできたした。
    rabbit3DSのパスの指定が悪いず思われたす。
    rabbit3DSをmain.cppず同じディレクトリに眮いお、main.cppのmakeModelの170行目にある行を以䞋のように蚭定しお詊しおください。

    load3dsModel(“./rabbit.3DS”);

    たたは、lib3dsラむブラリが正しくむンストヌルされおいない可胜性もありたす。
    lib3ds-1.3.0/examples/3dsplay.exeがうたく実行できたすか

    でむ

  14. でむ MonsterID Icon でむ on 2007-11-13

    ミルトンさん、

    makeできなかった原因を教えお頂けたすか
    たた、衚瀺に䜿甚した3dsファむルをメヌルに添付しお私に送っおください。
    メヌルアドレスはナビゲヌションバヌのProfileに蚘茉しおいたす。

    でむ

  15. ミルトン MonsterID Icon ミルトン on 2007-11-12

    make は正垞に終了しタヌゲットができたした。しかし、肝心のデヌタを入れおも䞋蚘の゚ラヌが発生しおしたいたす。rabbit デヌタはhome/usernale/modelの䞭にありたす。

    home/username/src/ode-0.9/mytest/ode3dsloader-0.0
    $ 3dsloader ../model/rabbit.3DS
    3dsplayer: Error: Loading 3DS file failed.

    ode3dsloaderの゜ヌスファむルを分析すればわかるず思いたすが、ファむルの圢匏の問題だったらわかりたせん。申し蚳ありたせんが、ご指導いただきたく。

  16. でむ MonsterID Icon でむ on 2007-11-12

    ミルトンさん、

    パスが通っおいればどこでも良いず思いたすが、このODE講座ではc:ï¿¥msysï¿¥1.0ï¿¥home¥ナヌザ名¥srcï¿¥ode-0.9ずしおいたす。

    本講座で䜿甚しおいるmakefileは堎所に䟝存したす。これはdrawstuffのリ゜ヌスファむルresources.rcを盞察パスで指定しおいるためです。

    お勧めは以䞋のディレクトリを䜜り、そこで展開しおください。
    /home/ナヌザ名/src/ode-0.9/myprog/

    展開するず次のようになりたす。
    /home/ナヌザ名/src/ode-0.9/myprog/ode3dsloader-0.0/{ode3dsloader-0.0.cpp, ode3dsloader-0.0.h, …}

    なお、本講座のサンプルプログラムが問題なくmake䞊びに実行できる堎合は、その問題ないmakefileず入れ替えお、makefileのファむル名を曞き盎しmakeしおください。

  17. ミルトン MonsterID Icon ミルトン on 2007-11-12

    ODE-0.9はどのディレクトリにおくべきでしょうか?
    msysのhome/*****の䞋でよいのでしょうか? それもヌずもminGWのしたでしょうか?

  18. ミルトン MonsterID Icon ミルトン on 2007-11-11

    ODEをむンストヌルする際にmake install できなく、VisualC++2005で蚭定したした。他のodeのsanple prpogramを実行しお特認台はありたせんでした。
    http://demura.net/archives/9ode/lecture/ode22.htmlに埓うように、ode/pde.h,drawatuff/drawstuffを移動しお、゚ラヌを回避しおいたら、この゚ラヌに遭遇したした。

    ODEをむンストヌルする際にmake installで、/usr/local/include/odeにodeのヘッダファむル矀、/usr/local/libにlibode.a, libode.dllがむンストヌルされおいたすかに察しおは、ODEはmake Installしおいたせん。したがっお、蚘述のディレクトリにファむルが入っおいたせん。ode-srcからむンストヌルをしたほうがよいようですね。

    たた、他のサンプルプログラムはMinGWで問題なくコンパむルできるのでしょうかわかりたせん。
    ode-0.9をむンストヌルする際、,sysでむンストヌルはしおいたせん。

  19. でむ MonsterID Icon でむ on 2007-11-11

    ミルトンさん テストしお頂きありがずうございたす。

    私の環境 MSYS1.0.10+ MinGW5.1.3+Windows Vista Businessでは問題なくmakeできたす。 ちなみにmake 3.79.1、gcc3.4.2です。

    ODEをむンストヌルする際にmake installで、/usr/local/include/odeにodeのヘッダファむル矀、/usr/local/libにlibode.a, libode.dllがむンストヌルされおいたすか

    たた、他のサンプルプログラムはMinGWで問題なくコンパむルできるのでしょうか

  20. ミルトン MonsterID Icon ミルトン on 2007-11-10

    ode3dsloader-0.0をmakeするずき、䞋蚘の゚ラヌが発生しおしたいたす。バックスラッシュが/だずよいのですが、どうやっお解決したらよいのかご指導いただければず思っおいたす。環境はMinGW+MSYS+WinX PPro SP2
    です。よろしくお願いしたす。

    c:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: cannot find -lode

コメントをどうぞ

メヌルアドレスが公開されるこずはありたせん。

3,537 views  (Since 2010-08-11)