-
Extracting Actor geometry
Posted on 21 July 2009 Neill No commentsSince 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.
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)
FBModelList 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 versionfprintf(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);}FBModelList 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
FBModelList 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
HFBModel 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
HFBModel 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о
HFBModel 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!
MotionBuilder, Programming Actor, MoCap, SDK, Source, TutorialsLeave a Reply
You must be logged in to post a comment.


English
Russian
Recent Comments