-
Извлечение геометрии актера
Дата: Июль 21st, 2009 Neill Комментариев нет
[lang_ru]С актером связано довольно много при работе с МоКапом. И если ставить эксперименты, то может понадобится вовсе собрать например своего актера. О сборке альтернативного актера я расскажу чуть позже, сейчас поделюсь как извлечь геометрию частей тела актера в отдельный файл и как потом это все рисовать в виде отдельного объекта.[/lang_ru][lang_en]
Since actor has quite a lot work with MoCap, actor is important part of working process. And if you wish to experiment, you may to collect actor geometry bodies. I will talk about building complete alternative actor later, now I will share how to extract the geometry body of the actor in a separate file and then how to output it in a separate MoBu model.
[/lang_en]
[lang_ru]Извлечение геометрии
Ниже представлен код по извлечению геометрии объекта и записи в отдельный файл (с именем этого объекта и расширением *.msh)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75FBModelList lModelList;
FBGetSelectedModels( lModelList );
for (int model=0; model<lModelList.GetCount(); model++ )
{
HFBModel lActorModel = lModelList.GetAt(model);
FBTrace( "%s\n", (char*)lActorModel->Name );
FBGeometry lGeom(lActorModel);
FBMesh lMesh(lActorModel);
FBString strFileName("C:\\");
strFileName = strFileName + lActorModel->Name;
strFileName = strFileName + ".msh";
FILE *f = fopen( strFileName, "w" );
if (f == NULL) return;
fseek(f, 0, 0);
fprintf(f, "01\n" ); // file version
fprintf(f, "%s\n", (char*) lActorModel->Name );
// extract geometry (vertices)
FBVertex vertex;
FBNormal normal;
fprintf(f, "%d\n", lGeom.VertexCount() );
for (int i=0; i<lGeom.VertexCount(); i++)
{
vertex = lGeom.VertexGet(i);
normal = lGeom.VertexNormalGet(i);
fprintf( f, "%f %f %f\n", vertex[0], vertex[1], vertex[2] );
fprintf( f, "%f %f %f\n", normal[0], normal[1], normal[2] );
}
// extract mesh (polygons)
fprintf( f, "%d\n", lMesh.PolygonCount() );
for (int i=0; i<lMesh.PolygonCount(); i++)
{
fprintf( f, "%d\n", lMesh.PolygonVertexCount(i) );
for (int j=0; j<lMesh.PolygonVertexCount(i); j++)
fprintf( f, "%d\n", lMesh.PolygonVertexIndex(i, j) );
}
fclose(f);
}Несколько уточнений к приложенному выше алгоритму:
1) прежде всего мы получаем список выделенных объектов в сцене и затем запускаем главный цикл по каждому такому объекту
1
2
3
4
5
6
7FBModelList lModelList;
FBGetSelectedModels( lModelList );
for (int model=0; model<lModelList.GetCount(); model++ )
{2) получить доступ к данным о вершинах, нормалях и полигонах объекта можно через классы FBMesh, FBGeometry, где в конструкторе следует указать саму модель
1
2
3
4
5
6
7HFBModel lActorModel = lModelList.GetAt(model);
FBTrace( "%s\n", (char*)lActorModel->Name );
FBGeometry lGeom(lActorModel);
FBMesh lMesh(lActorModel);3) класс FBGeometry дает нам информацию о наборе вершин каркаса
lGeom.VertexCount() – общее количество вершин
lGeom.VertexGet(i) – возвращает вершину с индексом i
lGeom.VertexNormalGet(i) – возвращает нормаль для вершины с индексом i
4) класс FBMesh дает нам информацию о наборе полигонов каркаса
lMesh.PolygonCount() – общее количество полигонов на каркас
lMesh.PolygonVertexCount(i) – количество вершин в полигоне с индексом i
lMesh.PolygonVertexIndex(i, j) - индекс j-й вершины полигона с индексом i
Модель с геометрией
Теперь для того чтобы отрисовать свою модель с геометрией актера, привожу код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127HFBModel pModel = new FBModel (mBodyName);
FBString fileName("c:\\actor\\");
fileName = fileName + (char*)mBodyName;
fileName = fileName + ".msh";
FILE *f = fopen( fileName, "r" );
if (f == NULL) return;
fseek( f, 0, 0 );
HFBGeometry lGeom = pModel->Geometry;
HFBMesh< pMesh = (HFBMesh) lGeom;
if (!pMesh) {
FBMesh lMesh(pModel);
pMesh = &lMesh;
}
char buffer[2048];
int count;
memset(buffer,0,sizeof(char)*2048);
fgets(buffer, 2048, f);
// check file version
if ( (buffer[0] != '0') || (buffer[1] != '1') ) return;
// skip
fgets(buffer, 2048, f); // mesh name
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &count );
bool res;
res = pMesh->GeometryBegin();
pMesh->VertexInit(count);
// step 1: create vertices
float x,y,z, p,q,w;
for (int i=0; i<count; i++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%f %f %f", &x, &y, &z );
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%f %f %f", &p, &q, &w );
pMesh->VertexNormalSet( (double)p, (double)q, (double)w, i );
pMesh->VertexSet( (double)x, (double)y, (double)z, i );
}
// step 2: create polygons
int ndx, pCount=0;
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &count );
for (int i=0; i<count; i++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &pCount );
pMesh->PolygonBegin();
for (int j=0; j<pCount; j++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &ndx );
pMesh->PolygonVertexAdd(ndx);
}
pMesh->PolygonEnd();
}
pMesh->GeometryEnd();
pModel->Show = true;
pModel->ResetDisplayList();Теперь некоторые пояснения по вышеприложенному коду:
1) создается новая пустая модель в сцене довольно просто
1HFBModel pModel = new FBModel (mBodyName);где mBodyName – имя модели
2) Изначально модель не содержит геометрический каркас, поэтому его нужно назначить
1
2
3FBMesh lMesh(pModel);
pMesh = &lMesh;Тем самым мы создали для модели новый каркас геометрии и его можно заполнять данными по вершинам, нормалям и полигонам.
3) В конце работы с геометрией и моделью важно эту модель показать и обновить дисплейные списки, иначе ничего в сцене не увидим
1
2
3pModel->Show = true;
pModel->ResetDisplayList();Вот собственно и все на сегодня, до новых встреч!
[/lang_ru]
[lang_en]Extracting geometry
Below is the code to derive the geometry of the object and write in a separate file (with the name of the model and the extension *. msh)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75FBModelList lModelList;
FBGetSelectedModels( lModelList );
for (int model=0; model<lModelList.GetCount(); model++ )
{
HFBModel lActorModel = lModelList.GetAt(model);
FBTrace( "%s\n", (char*)lActorModel->Name );
FBGeometry lGeom(lActorModel);
FBMesh lMesh(lActorModel);
FBString strFileName("C:\\");
strFileName = strFileName + lActorModel->Name;
strFileName = strFileName + ".msh";
FILE *f = fopen( strFileName, "w" );
if (f == NULL) return;
fseek(f, 0, 0);
fprintf(f, "01\n" ); // file version
fprintf(f, "%s\n", (char*) lActorModel->Name );
// extract geometry (vertices)
FBVertex vertex;
FBNormal normal;
fprintf(f, "%d\n", lGeom.VertexCount() );
for (int i=0; i<lGeom.VertexCount(); i++)
{
vertex = lGeom.VertexGet(i);
normal = lGeom.VertexNormalGet(i);
fprintf( f, "%f %f %f\n", vertex[0], vertex[1], vertex[2] );
fprintf( f, "%f %f %f\n", normal[0], normal[1], normal[2] );
}
// extract mesh (polygons)
fprintf( f, "%d\n", lMesh.PolygonCount() );
for (int i=0; i<lMesh.PolygonCount(); i++)
{
fprintf( f, "%d\n", lMesh.PolygonVertexCount(i) );
for (int j=0; j<lMesh.PolygonVertexCount(i); j++)
fprintf( f, "%d\n", lMesh.PolygonVertexIndex(i, j) );
}
fclose(f);
}A few clarifications to above algorithm:
1) Above all, we get a list of selected objects in a scene and then run the main loop for each object
1
2
3
4
5
6
7FBModelList lModelList;
FBGetSelectedModels( lModelList );
for (int model=0; model<lModelList.GetCount(); model++ )
{2) Access to data of the vertices, normals and polygons is available with classes FBMesh, FBGeometry, where in the constructor should be passed the model object
1
2
3
4
5
6
7HFBModel lActorModel = lModelList.GetAt(model);
FBTrace( "%s\n", (char*)lActorModel->Name );
FBGeometry lGeom(lActorModel);
FBMesh lMesh(lActorModel);3) Class FBGeometry gives us information about the vertices of the mesh
lGeom.VertexCount() – общее количество вершин
lGeom.VertexGet(i) – возвращает вершину с индексом i
lGeom.VertexNormalGet(i) – возвращает нормаль для вершины с индексом i
4) Class FBMesh gives us information about the polygons of the mesh
lMesh.PolygonCount() – общее количество полигонов на каркас
lMesh.PolygonVertexCount(i) – количество вершин в полигоне с индексом i
lMesh.PolygonVertexIndex(i, j) - индекс j-й вершины полигона с индексом i
Model with actor geometry
Now, in order to create a model with the actor’s geometry, I giving the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127HFBModel pModel = new FBModel (mBodyName);
FBString fileName("c:\\actor\\");
fileName = fileName + (char*)mBodyName;
fileName = fileName + ".msh";
FILE *f = fopen( fileName, "r" );
if (f == NULL) return;
fseek( f, 0, 0 );
HFBGeometry lGeom = pModel->Geometry;
HFBMesh< pMesh = (HFBMesh) lGeom;
if (!pMesh) {
FBMesh lMesh(pModel);
pMesh = &lMesh;
}
char buffer[2048];
int count;
memset(buffer,0,sizeof(char)*2048);
fgets(buffer, 2048, f);
// check file version
if ( (buffer[0] != '0') || (buffer[1] != '1') ) return;
// skip
fgets(buffer, 2048, f); // mesh name
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &count );
bool res;
res = pMesh->GeometryBegin();
pMesh->VertexInit(count);
// step 1: create vertices
float x,y,z, p,q,w;
for (int i=0; i<count; i++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%f %f %f", &x, &y, &z );
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%f %f %f", &p, &q, &w );
pMesh->VertexNormalSet( (double)p, (double)q, (double)w, i );
pMesh->VertexSet( (double)x, (double)y, (double)z, i );
}
// step 2: create polygons
int ndx, pCount=0;
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &count );
for (int i=0; i<count; i++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &pCount );
pMesh->PolygonBegin();
for (int j=0; j<pCount; j++)
{
memset(buffer,0,sizeof(char)*2048);
fgets( buffer, 2048, f );
sscanf( buffer, "%d", &ndx );
pMesh->PolygonVertexAdd(ndx);
}
pMesh->PolygonEnd();
}
pMesh->GeometryEnd();
pModel->Show = true;
pModel->ResetDisplayList();Now some notes on code above:
1) creates a new empty model in the scene is quite simpleо
1HFBModel pModel = new FBModel (mBodyName);где mBodyName – имя модели
2) Initially, the model does not include the geometric framework, so you need to appoint
FBMesh lMesh(pModel);
pMesh = &lMesh;
Thus, we created a model for a new geometry and you can fill it with data about the vertices, normals and polygons.
3) At the end of out work, It’s important to show the model and update the display list, otherwise we couldn’t see our new model in the scene.
pModel->Show = true;
pModel->ResetDisplayList();
This is actually all for today, until the new meetings!
[/lang_en]
MotionBuilder, Программирование Actor, MoCap, SDK, Source, TutorialsДобавить комментарий


Свежие комментарии