University of Southern CaliforniaUSC
USC ICT TwitterUSC ICT FacebookUSC ICT YouTube

SmartBody integration in game engine | General SmartBody Discussion | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
SmartBody integration in game engine
June 25, 2014
5:14 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi all,

 

First of all, thanks for developing SmartBody, it's a really awesome technology which saves game and engine developers tons of hard work!

 

My name is Alex, I'm a videogame / engine programmer, and I have to integrate smartbody in the 3D engine of my company. I have read the doc and installed SmartBody, but the main barrier I have at this moment is finding the simplest C++ available code for rendering a SmartBody character, as I need to integrate the rendering process in a C++ game engine.

Any ideas what could I do? are there any very simple demos which handles the rendering part (extracting the relevant data from a SmartBody character and mesh deformation through GPU, in OpenGL or DirectX)?

 

thanks in advance!

 

Alex

June 25, 2014
11:14 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

The simplest rendering example is probably from one of the mobile ports )(say, android\sbjniapp\jni). There is a setup phase where the drawable objects are added to the scene graph, then a render phase where they are drawn. I should probably set up a sample desktop project that shows this as well.

void initCharacterScene()
{
    SmartBody::SBScene* scene = SmartBody::SBScene::getScene();
    std::vector<std::string> charNames = scene->getCharacterNames();
    for (size_t i = 0; i < charNames.size(); i++)
    {
        SmartBody::SBCharacter* character = scene->getCharacter(charNames[i]);
        if (!character)
            continue;

        // add skeletons and mesh    
        if (character->scene_p)
        {
            SmartBody::SBScene::getScene()->getRootGroup()->remove(character->scene_p);
            character->scene_p->unref();
            character->scene_p = NULL;
        }

        character->scene_p = new SkScene();
        character->scene_p->ref();
        character->scene_p->init(character->getSkeleton());
        bool visible = character->getBoolAttribute("visible");
        if (visible)
            character->scene_p->visible(true);
        else
            character->scene_p->visible(false);
        scene->getRootGroup()->add(character->scene_p);

        LOG("Character %s's skeleton added to the scene.", charNames[i].c_str());        
        character->dMeshInstance_p =  new DeformableMeshInstance();
       character->dMeshInstance_p->setPawn(character);
        LOG("Character %s's deformable mesh reset.", charNames[i].c_str());

        std::string dMeshAttrib = character->getStringAttribute("deformableMesh");
        character->setStringAttribute("deformableMesh", dMeshAttrib);
        LOG("Character %s's deformable mesh %s added to the scene.", charNames[i].c_str(), dMeshAttrib.c_str());
    }
}
void renderFrame()
{
   SmartBody::SBScene* scene = SmartBody::SBScene::getScene();
    SrCamera* defaultCam = scene->getCamera("defaultCamera");
    if (!defaultCam) return;

    SrCamera& cam = *defaultCam;

    // Just fill the screen with a color.
    glClearColor(0.6f,0.6f,0.6f,1);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    glLight(0, light1);
    glLight(1, light2);
    glEnable(GL_TEXTURE_2D);

    SrMat mat;
    glMatrixMode ( GL_PROJECTION );
    glLoadMatrixf ( (const float*)cam.get_perspective_mat(mat) );

    //----- Set Visualisation -------------------------------------------
    glMatrixMode ( GL_MODELVIEW );
    glLoadMatrixf ( (const float*)cam.get_view_mat(mat) );

        SbmTextureManager& texm = SbmTextureManager::singleton();
        texm.updateTexture();

    // draw a ground plane
    float planeSize  = 300.f;
    SrVec quad[4] = { SrVec(planeSize, 0.f, planeSize), SrVec(-planeSize, 0.f, planeSize), SrVec(-planeSize,0.f,-planeSize), SrVec(planeSize, 0.f, -planeSize) };
    SrVec quadN[4] = { SrVec(0.f, 1.f, 0.f), SrVec(0.f, 1.f, 0.f), SrVec(0.f, 1.f, 0.f), SrVec(0.f, 1.f, 0.f) };
    GLfloat quadColor[16] = { 0.2f,0.2f, 0.2f, 1.f , 0.3f,0.3f,0.3f, 1.f, 0.5f,0.5f,0.5f,1.f, 0.25f,0.25f,0.25f,1.f };
    unsigned short indices[] = {0,1,2, 0,2,3};

    glShadeModel(GL_SMOOTH);
    glDisable(GL_CULL_FACE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, (GLfloat*)&quad[0]);
    glColorPointer(4, GL_FLOAT, 0, quadColor);
    glNormalPointer(GL_FLOAT, 0, (GLfloat*)&quadN[0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
    glDisableClientState(GL_COLOR_ARRAY);

    glEnable(GL_LIGHTING);
    
const std::vector<std::string>& pawns = SmartBody::SBScene::getScene()->getPawnNames();
    for (std::vector<std::string>::const_iterator pawnIter = pawns.begin();
        pawnIter != pawns.end();
        pawnIter++)
    {
        SmartBody::SBPawn* pawn = SmartBody::SBScene::getScene()->getPawn((*pawnIter));
        if(pawn->dMeshInstance_p)
        {            
            pawn->dMeshInstance_p->setVisibility(1);
            pawn->dMeshInstance_p->update();
            SrGlRenderFuncs::renderDeformableMesh(pawn->dMeshInstance_p);
        }
    }
}

There are some examples of connecting SmartBody to game engines (Ogre, etc.) as well.

Ari



June 26, 2014
7:31 am
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

thank you so much Ari, that was very helpful!!

June 27, 2014
6:06 pm
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

Hi,

After downloading the source code through subversion and analyzing the android port, I have been able to go forward, but I have a problem at this moment.

For some reason, I'm not able to assign the "dae" file to my only character in scene, so when I try to loop through the submesh, I get a crash (the number of submeshes is zero in that case).

pPawn->dMeshInstance_p->_mesh is null, but pPawn->dMeshInstance_p->_skeleton and pPawn->dMeshInstance_p->_character aren't. I use a python script and two small fragments of code in C++:

Script brad.py:
----------------------------------------------------------------------------------------------------------------------
print "|--------------------------------------------|"
print "| brad.py |"
print "|--------------------------------------------|"

### Load data/sbm-common assets
scene.addAssetPath('motion', 'data/ChrBrad')
scene.addAssetPath('mesh', 'data/mesh')
scene.loadAssets()
scene.setScale(1.0)

# map to the SmartBody standard
scene.run("zebra2-map.py")
zebra2Map = scene.getJointMapManager().getJointMap("zebra2")
bradSkeleton = scene.getSkeleton('ChrBrad.sk')
zebra2Map.applySkeleton(bradSkeleton)
bradMotion = scene.getMotion('ChrBrad@Idle01_BeatHighBt01')
zebra2Map.applyMotion(bradMotion)

brad = scene.createCharacter("ChrBrad", "")
bradSkeleton = scene.createSkeleton("ChrBrad.sk")
brad.setSkeleton(bradSkeleton)
bradHPR = SrVec(0, 0, 0)
brad.setHPR(bradHPR)
bradPos = SrVec(0.0, 0.0, 0.0)
brad.setPosition(bradPos)
brad.createStandardControllers()
# deformable mesh
brad.setStringAttribute("deformableMesh", "ChrBrad.dae")
----------------------------------------------------------------------------------------------------------------------

 

First part of code (m_pChar is a member variable of type SmartBody::SBCharacter*):
----------------------------------------------------------------------------------------------------------------------
SmartBody::SBScene* pSc = SmartBody::SBScene::getScene();
m_pListener = new SimpleListener();
pSc->addSceneListener(m_pListener);
pSc->getSimulationManager()->setupTimer();
pSc->getSimulationManager()->setTime(0.0);
pSc->getSimulationManager()->start();
pSc->addAssetPath("script", "data/scripts");
pSc->runScript("brad.py");

std::vector<std::string> charNames = pSc->getCharacterNames();
for (size_t i = 0; i < charNames.size(); i++) {
    m_pChar = pSc->getCharacter(charNames[i]);
    if (!m_pChar)
        continue;
    // add skeletons and mesh
    if (m_pChar->scene_p) {
        SmartBody::SBScene::getScene()->getRootGroup()->remove(m_pChar->scene_p);
        m_pChar->scene_p->unref();
        m_pChar->scene_p = NULL;
    }
    m_pChar->scene_p = new SkScene();
    m_pChar->scene_p->ref();
    m_pChar->scene_p->init(m_pChar->getSkeleton());
    m_pChar->scene_p->visible(true);
    pSc->getRootGroup()->add(m_pChar->scene_p);
    LOG("Character %s's skeleton added to the scene.n", charNames[i].c_str());
    m_pChar->dMeshInstance_p = new DeformableMeshInstance();
    m_pChar->dMeshInstance_p->setPawn(m_pChar);
    LOG("Character %s's deformable mesh reset.n", charNames[i].c_str());
    std::string dMeshAttrib = m_pChar->getStringAttribute("deformableMesh");
    m_pChar->setStringAttribute("deformableMesh", "dMeshAttrib");
    m_pChar->dMeshInstance_p->setVisibility(1);
    LOG("Character %s's deformable mesh %s added to the scene.n", charNames[i].c_str(), dMeshAttrib.c_str());
}

int iNMotions = pSc->getNumMotions();
int iNSkeletons = pSc->getNumSkeletons();
int iNCharacters = pSc->getNumCharacters();
int iNPawns = pSc->getNumPawns();
int iNScripts = pSc->getNumScripts();
LOG("Loaded %d motions, %d skeletons, %d characters, %d pawns and %d scriptsn", iNMotions,iNSkeletons,iNCharacters,iNPawns,iNScripts);
----------------------------------------------------------------------------------------------------------------------

 

When I try to do the update and render part, I get a crash:

Update and render part:
----------------------------------------------------------------------------------------------------------------------

SmartBody::SBScene* pSc = SmartBody::SBScene::getScene();
pSc->getSimulationManager()->updateTimer(fDeltaTime);
pSc->update();

const std::vector<std::string>& vPawn = SmartBody::SBScene::getScene()->getPawnNames();
for (std::vector<std::string>::const_iterator pawnIter = vPawn.begin(); pawnIter != vPawn.end(); pawnIter++) {
    SmartBody::SBPawn* pPawn = SmartBody::SBScene::getScene()->getPawn((*pawnIter));
    if(pPawn->dMeshInstance_p) {
        pPawn->dMeshInstance_p->update();
        DeformableMesh* pMesh = pPawn->dMeshInstance_p->getDeformableMesh();
        std::vector<SbmSubMesh*>& vSubMesh = pMesh->subMeshList;
        for (uint i = 0; i < vSubMesh.size(); i++) { // ->crash, as vSubMesh.size() is zero
            SbmSubMesh* pSubMesh = vSubMesh.at(i);
            // Rendering process here...
        }
    }
}

----------------------------------------------------------------------------------------------------------------------

Please, what could I do to fix or workaround the problem? I've tried modifying the paths and copying the data file and its textures to other locations but I have the same problem every time.

Thaks in advance (again),

Alex

June 27, 2014
9:19 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

I left out this drawing code to draw the skeletons which is in the android port. You might want to use it to test out that the character is present:

-------------------------------------------

    static SrVec jointPos[200];
    static unsigned short boneIdx[400];

    SmartBody::SBScene* scene = SmartBody::SBScene::getScene();
    std::vector<std::string> characterNames = scene->getCharacterNames();

    for (std::vector<std::string>::iterator iter = characterNames.begin();
        iter != characterNames.end();
        iter++)
    {
        SmartBody::SBCharacter* character = scene->getCharacter(*iter);

        SmartBody::SBSkeleton* skeleton = character->getSkeleton();
        skeleton->update_global_matrices();
        std::map<int,int> indexMap;
        //LOG("Skeleton number of joints = %d", skeleton->joints().size());
        for (int i=0;i<skeleton->joints().size();i++)
        {
            SkJoint* joint = skeleton->joints()[i];
            SrVec pos = joint->gmat().get_translation();
            jointPos[i] = pos;
            //LOG("joint pos = %f %f %f",  pos[0],pos[1],pos[2]);
            indexMap[joint->index()] = i;
            boneIdx[i*2+0] = joint->index();
            if (joint->parent())
                boneIdx[i*2+1] = joint->parent()->index();
            else
                boneIdx[i*2+1] = joint->index();
        }

        for (int i=0;i<skeleton->joints().size();i++)
        {
            boneIdx[i*2] = indexMap[boneIdx[i*2]];
            boneIdx[i*2+1] = indexMap[boneIdx[i*2+1]];
        }

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, (const GLfloat*)&jointPos[0]);
        //glDrawArrays(GL_POINTS, 0, sk->joints().size());
        glDrawElements(GL_LINES,skeleton->joints().size()*2,GL_UNSIGNED_SHORT, boneIdx);
        glDisableClientState(GL_VERTEX_ARRAY);
    }

 

-------------------------------------------

To get the deformable mesh working, you need to run this code:

SmartBody::SBAssetManager* assetManager = scene->getAssetManager();
DeformableMesh* mesh = assetManager->getDeformableMesh("ChrBrad.dae");

if (!pChar->dMeshInstance_p)
    pChar->dMeshInstance_p = new DeformableMeshInstance();
pChar->dMeshInstance_p->setDeformableMesh(mesh);
pChar->dMeshInstance_p->setPawn(pawn);
if (name == "mesh") // setting static mesh
{
   pChar->dMeshInstance_p->setToStaticMesh(true);
}
LOG("has mesh %s, num. of vertices = %d", mesh->getName().c_str(), mesh->posBuf.size());

 

Let me know if that works for you.

 

Ari

July 1, 2014
11:05 am
Avatar
Member
Members
Forum Posts: 16
Member Since:
June 25, 2014
sp_UserOfflineSmall Offline

thank you very much for your help Ari, it works perfectly!

 

Alex

Forum Timezone: America/Los_Angeles

Most Users Ever Online: 733

Currently Online: mcclurelloyd91, Andreytielo, kvistaagesen6, shorebagger6, rubingriffith1, campbennedsen38, carrollpratt5, fosskrog0, magnussonmagnusson3, zhuwarner26, dreyer26guerrero, miscreantunderc69, BernardFaulkner25
72 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

jwwalker: 80

jyambao: 52

rbaral: 47

adiaz: 30

WargnierP: 29

lucky7456969: 28

mbarros: 28

avida.matt: 26

JonathanW: 24

laguerre: 23

Member Stats:

Guest Posters: 69

Members: 122101

Moderators: 3

Admins: 4

Forum Stats:

Groups: 1

Forums: 5

Topics: 531

Posts: 2495