void CharacterModel::convertMaterials(std::string configfile)
{
    getMaterials().clear();
    UInt32 mcnt = 0;
    PathHandler ph;
    
    ph.setBaseFile(configfile.c_str());
       
    for(int mid = 0; mid < _coreModel->getCoreMaterialCount(); mid++)
    {
        CalCoreMaterial *coremat = _coreModel->getCoreMaterial(mid);
        SimpleMaterialPtr mat = SimpleMaterial::create();

        beginEditCP(mat);

        CalCoreMaterial::Color &calamb = coremat->getAmbientColor();
        CalCoreMaterial::Color &caldif = coremat->getDiffuseColor();
        CalCoreMaterial::Color &calspec = coremat->getSpecularColor();

        mat->setAmbient(Color3f(calamb.red / 255.0f, calamb.green / 255.0f, calamb.blue / 255.0f));
        mat->setDiffuse(Color3f(caldif.red / 255.0f, caldif.green / 255.0f, caldif.blue / 255.0f));
        mat->setSpecular(Color3f(calspec.red / 255.0f, calspec.green / 255.0f, calspec.blue / 255.0f));
        
        mat->setShininess(coremat->getShininess() * 100.f);
        mat->setLit(true);
        mat->setColorMaterial(GL_NONE);
        
        for(int mapId = 0; mapId < coremat->getMapCount(); mapId++)
        {
            std::string file = coremat->getMapFilename(mapId);
            std::string pfile = ph.findFile(file.c_str());
            SINFO << "Loading texture '" << pfile << "'..." << endLog;

            ImagePtr img = Image::create();
            
             if(!img->read(pfile.c_str()))
            {
                SWARNING << "CharacterModel::convertMaterials: error "
                         << "loading image " << file << endLog;
            }
            else
            {
                // amz with my test scene paladin.cfg all textures were
                // upside down so I disabled the vertical flipping perhaps
                // they fixed the bug in Cal3D?
#if 0
                beginEditCP(img);
                {
                // For some reason Cal3D expects textures upside down ???
                UInt32 bpl = img->getBpp() * img->getWidth();
                UChar8 *t = img->getData(), 
                       *b = t + (img->getHeight() - 1) * bpl,
                        dum;

                for(UInt32 y = img->getHeight() / 2; y > 0; --y)
                {
                    for(UInt32 x = bpl; x > 0; --x, ++t, ++b)
                    {
                        dum = *t;
                        *t = *b;
                        *b = dum;
                    }
                    b -= bpl * 2;
                }
                }
                endEditCP(img);
#endif
                
                TextureChunkPtr tex = TextureChunk::create();
                
                beginEditCP(tex);
                tex->setImage(img);
                tex->setEnvMode(GL_MODULATE);
                endEditCP(tex);
                
                mat->addChunk(tex);
            }
        }
            
        endEditCP(mat);
        
        coremat->setUserData((Cal::UserData)mcnt);
        getMaterials().push_back(mat);
        mcnt ++;
    }    
}
bool Viewer::onInit()
{
  // load all textures and store the D3D texture object id in the corresponding map in the material
  int materialId;
  for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
  {
    // get the core material
    CalCoreMaterial *pCoreMaterial;
    pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);

    // loop through all maps of the core material
    int mapId;
    for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
    {
      // get the filename of the texture
      std::string strFilename;
      strFilename = pCoreMaterial->getMapFilename(mapId);

      // load the texture from the file
      LPDIRECT3DTEXTURE9 texture;
      texture = loadTexture(strFilename);

      // store the d3d texture id in the user data of the map
      pCoreMaterial->setMapUserData(mapId, (Cal::UserData)texture);
    }
  }

  // attach all meshes to the model
  int meshId;
  for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
  {
    m_calModel->attachMesh(meshId);
  }

  // set the material set of the whole model
  m_calModel->setMaterialSet(0);

  // set initial animation state
  m_currentAnimationId = 0;
  m_leftAnimationTime = m_calCoreModel->getCoreAnimation(m_currentAnimationId)->getDuration() - m_blendTime;
  if(m_calCoreModel->getCoreAnimationCount() > 1)
  {
    m_calModel->getMixer()->executeAction(m_currentAnimationId, 0.0f, m_blendTime);
  }
  else
  {
    m_calModel->getMixer()->blendCycle(m_currentAnimationId, 1.0f, 0.0f);
  }

  // we're done
  std::cout << "Initialization done." << std::endl;
  std::cout << std::endl;
  std::cout << "Quit the viewer by pressing 'q' or ESC" << std::endl;
  std::cout << std::endl;

  m_lastTick = Tick::getTick();

  if(!loadVertexBuffer())
    return false;

  // 
  //  There are changes here between Direct3D SDK 9 and Direct3D SDK 9 summer 2003 update
  //

  /* Original SDK

  LOGFONT LogFont = {24,0,0,0,FW_NORMAL,false,false,false,DEFAULT_CHARSET,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,"Arial"};

  D3DXCreateFontIndirect(g_pD3DDevice,&LogFont ,&m_pFont);

  */

  ///* Update

  D3DXCreateFont(g_pD3DDevice,24,0,0,0,false,DEFAULT_CHARSET,CLIP_DEFAULT_PRECIS,
    PROOF_QUALITY,DEFAULT_PITCH, "Arial", &m_pFont);

  //*/




  return true;
}
Exemple #3
0
bool Viewer::onInit()
{
  // load all textures and store the opengl texture id in the corresponding map in the material
  int materialId;
  for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
  {
    // get the core material
    CalCoreMaterial *pCoreMaterial;
    pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);

    // loop through all maps of the core material
    int mapId;
    for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
    {
      // get the filename of the texture
      std::string strFilename;
      strFilename = pCoreMaterial->getMapFilename(mapId);

      // load the texture from the file
      GLuint textureId;
      textureId = loadTexture(strFilename);

      // store the opengl texture id in the user data of the map
      pCoreMaterial->setMapUserData(mapId, (Cal::UserData)textureId);
    }
  }

  // attach all meshes to the model
  int meshId;
  for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
  {
    m_calModel->attachMesh(meshId);
  }

  // set the material set of the whole model
  m_calModel->setMaterialSet(0);

  // set initial animation state
  if(m_calCoreModel->getCoreAnimationCount() > 0)
  {
    m_currentAnimationId = 0;
    m_leftAnimationTime = m_calCoreModel->getCoreAnimation(m_currentAnimationId)->getDuration() - m_blendTime;
    if(m_calCoreModel->getCoreAnimationCount() > 1)
    {
      m_calModel->getMixer()->executeAction(m_currentAnimationId, 0.0f, m_blendTime);
    }
    else
    {
      m_calModel->getMixer()->blendCycle(m_currentAnimationId, 1.0f, 0.0f);
    }
  }
  else
  {
    m_currentAnimationId = -1;
    m_leftAnimationTime = -1.0f;
  }


  // Disable internal data
  // this disable spring system


  std::cout << "Disable internal." << std::endl;
  m_calModel->disableInternalData();

  m_lastTick = Tick::getTick();

  glewInit();

  if (!GLEW_ARB_vertex_program)
  {
      std::cerr << "Error ARB_vertex_program OpenGL extension not found." << std::endl;
	  return false;
  }

  if (!GLEW_ARB_vertex_buffer_object)
  {
      std::cerr << "Error ARB_vertex_buffer_object OpenGL extension not found." << std::endl;
	  return false;
  }


  if(!loadBufferObject())
  {
      std::cerr << "Error loading vertex buffer object." << std::endl;
	  return false;
  }


  if(!loadVertexProgram())
  {
      std::cerr << "Error loading vertex program." << std::endl;
	  return false;
  }
  


  // we're done
  std::cout << "Initialization done." << std::endl;
  std::cout << std::endl;
  std::cout << "Quit the viewer by pressing 'q' or ESC" << std::endl;
  std::cout << std::endl;

  

  return true;
}
Exemple #4
0
bool Viewer::onInit()
{
  // load all textures and store the D3D texture object id in the corresponding map in the material
  int materialId;
  for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
  {
    // get the core material
    CalCoreMaterial *pCoreMaterial;
    pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);

    // loop through all maps of the core material
    int mapId;
    for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
    {
      // get the filename of the texture
      std::string strFilename;
      strFilename = pCoreMaterial->getMapFilename(mapId);

      // load the texture from the file
      LPDIRECT3DTEXTURE9 texture;
      texture = loadTexture(strFilename);

      // store the d3d texture id in the user data of the map
      pCoreMaterial->setMapUserData(mapId, (Cal::UserData)texture);
    }
  }

  // attach all meshes to the model
  int meshId;
  for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
  {
    m_calModel->attachMesh(meshId);
  }

  // set the material set of the whole model
  m_calModel->setMaterialSet(0);

  // set initial animation state
  m_currentAnimationId = 0;
  m_leftAnimationTime = m_calCoreModel->getCoreAnimation(m_currentAnimationId)->getDuration() - m_blendTime;
  if(m_calCoreModel->getCoreAnimationCount() > 1)
  {
    m_calModel->getMixer()->executeAction(m_currentAnimationId, 0.0f, m_blendTime);
  }
  else
  {
    m_calModel->getMixer()->blendCycle(m_currentAnimationId, 1.0f, 0.0f);
  }

  // Enable tangents

  for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++) 
  { 
      int submeshId; 
      for(submeshId = 0; submeshId < m_calModel->getMesh(meshId)->getSubmeshCount() ; submeshId++) 
      { 
          CalSubmesh * Submesh = m_calModel->getMesh(meshId)->getSubmesh(submeshId); 
          CalCoreMaterial *pCoreMaterial= m_calCoreModel->getCoreMaterial(Submesh->getCoreMaterialId()); 

		  if(pCoreMaterial->getMapCount()==2)
		  {
		     if(strstr(pCoreMaterial->getMapFilename(1).c_str(),"bump")!=NULL)
			 {
                 Submesh->enableTangents(1,true);				 
			 }			 
		  }          
      } 
  }

  m_bBump=g_bCanDot3;

  
  // we're done
  std::cout << "Initialization done." << std::endl;
  std::cout << std::endl;
  std::cout << "Quit the viewer by pressing 'q' or ESC" << std::endl;
  std::cout << std::endl;

  m_lastTick = Tick::getTick();

  if(!loadVertexBuffer())
	  return false;

  if(!loadVertexShader())
	  return false;

  loadFont();

  // CreateNormalizationCubeMap();
     
  return true;
}
Exemple #5
0
bool Model::load(const std::string& _strFilename)
{
  // open the model configuration file
  std::ifstream file;
  std::string strFilename(core->adjustFilenameCase(_strFilename));
  file.open(strFilename.c_str(), std::ios::in | std::ios::binary);
  if(!file)
  {
	  std::ostringstream os;
	  os << "Failed to open model configuration file '" << strFilename << "'." << std::endl;
	  errorLog(os.str());
	 return false;
  }

  // initialize the data path
  std::string strPath = m_path;

  // initialize the animation count
  int animationCount;
  animationCount = 0;

  // parse all lines from the model configuration file
  int line;
  for(line = 1; ; line++)
  {
    // read the next model configuration line
    std::string strBuffer;
    std::getline(file, strBuffer);

    // stop if we reached the end of file
    if(file.eof()) break;

    // check if an error happend while reading from the file
    if(!file)
    {
      std::cerr << "Error while reading from the model configuration file '" << strFilename << "'." << std::endl;
      return false;
    }

    // find the first non-whitespace character
    std::string::size_type pos;
    pos = strBuffer.find_first_not_of(" \t");

    // check for empty lines
    if((pos == std::string::npos) || (strBuffer[pos] == '\n') || (strBuffer[pos] == '\r') || (strBuffer[pos] == 0)) continue;

    // check for comment lines
    if(strBuffer[pos] == '#') continue;

    // get the key
    std::string strKey;
    strKey = strBuffer.substr(pos, strBuffer.find_first_of(" =\t\n\r", pos) - pos);
    pos += strKey.size();

    // get the '=' character
    pos = strBuffer.find_first_not_of(" \t", pos);
    if((pos == std::string::npos) || (strBuffer[pos] != '='))
    {
      std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
      return false;
    }

    // find the first non-whitespace character after the '=' character
    pos = strBuffer.find_first_not_of(" \t", pos + 1);

    // get the data
    std::string strData;
    strData = strBuffer.substr(pos, strBuffer.find_first_of("\n\r", pos) - pos);

    // handle the model creation
    if(strKey == "scale")
    {
      // set rendering scale factor
      m_renderScale = atof(strData.c_str());
    }
    else if(strKey == "path")
    {
      // set the new path for the data files if one hasn't been set already
      if (m_path == "") strPath = strData;
    }
    else if(strKey == "skeleton")
    {
      // load core skeleton
      std::cout << "Loading skeleton '" << strData << "'..." << std::endl;
      if(!m_calCoreModel->loadCoreSkeleton(strPath + strData))
      {
        CalError::printLastError();
        return false;
      }
    }
    else if(strKey == "animation")
    {
      // load core animation
      std::cout << "Loading animation '" << strData << "'..." << std::endl;
      m_animationId[animationCount] = m_calCoreModel->loadCoreAnimation(strPath + strData);
      if(m_animationId[animationCount] == -1)
      {
        CalError::printLastError();
        return false;
      }

      animationCount++;
    }
    else if(strKey == "mesh")
    {
      // load core mesh
      std::cout << "Loading mesh '" << strData << "'..." << std::endl;
      if(m_calCoreModel->loadCoreMesh(strPath + strData) == -1)
      {
        CalError::printLastError();
        return false;
      }
    }
    else if(strKey == "material")
    {
      // load core material
      std::cout << "Loading material '" << strData << "'..." << std::endl;
      if(m_calCoreModel->loadCoreMaterial(strPath + strData) == -1)
      {
        CalError::printLastError();
        return false;
      }
    }
    else
    {
      std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
      return false;
    }
  }

  // explicitely close the file
  file.close();

  // load all textures and store the opengl texture id in the corresponding map in the material
  int materialId;
  for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
  {
    // get the core material
    CalCoreMaterial *pCoreMaterial;
    pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);

    // loop through all maps of the core material
    int mapId;
    for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
    {
      // get the filename of the texture
      std::string strFilename;
      strFilename = pCoreMaterial->getMapFilename(mapId);

      // load the texture from the file
      GLuint textureId;
	  pngInfo info;
      textureId = pngBind((strPath + strFilename).c_str(), PNG_BUILDMIPMAPS, PNG_ALPHA, &info, GL_CLAMP, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
		  //loadTexture(strPath + strFilename);

      // store the opengl texture id in the user data of the map
      pCoreMaterial->setMapUserData(mapId, (Cal::UserData)textureId);
    }
  }

  // make one material thread for each material
  // NOTE: this is not the right way to do it, but this viewer can't do the right
  // mapping without further information on the model etc.
  for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
  {
    // create the a material thread
    m_calCoreModel->createCoreMaterialThread(materialId);

    // initialize the material thread
    m_calCoreModel->setCoreMaterialId(materialId, 0, materialId);
  }

  // Calculate Bounding Boxes

  m_calCoreModel->getCoreSkeleton()->calculateBoundingBoxes(m_calCoreModel);

  m_calModel = new CalModel(m_calCoreModel);

  // attach all meshes to the model
  int meshId;
  for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
  {
    m_calModel->attachMesh(meshId);
  }

  // set the material set of the whole model
  m_calModel->setMaterialSet(0);

  // set initial animation state
  /*
  m_state = STATE_MOTION;
  m_calModel->getMixer()->blendCycle(m_animationId[STATE_MOTION], m_motionBlend[0], 0.0f);
  m_calModel->getMixer()->blendCycle(m_animationId[STATE_MOTION + 1], m_motionBlend[1], 0.0f);
  m_calModel->getMixer()->blendCycle(m_animationId[STATE_MOTION + 2], m_motionBlend[2], 0.0f);
  */

  return true;
}
Exemple #6
0
bool Cal3DCoreHelper::loadCfg(const std::string &strFilename)
{
    // open the model configuration file
    m_name = strFilename;
#if MAX_PRODUCT_VERSION_MAJOR > 14
    TSTR tmpN;
    tmpN.FromUTF8(m_name.c_str());
    TSTR tmpName = myVRMLName(tmpN);
    m_VrmlName = tmpName.ToCStr().data();
#else
    m_VrmlName = myVRMLName(m_name.c_str());
#endif

    std::ifstream file;
    file.open(strFilename.c_str(), std::ios::in | std::ios::binary);
    if (!file)
    {
        std::cerr << "Failed to open model configuration file '" << strFilename << "'." << std::endl;
        return false;
    }
    size_t pathend = strFilename.find_last_of("/\\");
    if (pathend != std::string::npos)
    {
        m_path = strFilename.substr(0, pathend + 1);
    }

    // initialize the data path
    std::string strPath = m_path;

    // initialize the animation count
    m_animationCount = 0;

    // parse all lines from the model configuration file
    int line;
    for (line = 1;; line++)
    {
        // read the next model configuration line
        std::string strBuffer;
        std::getline(file, strBuffer);

        // stop if we reached the end of file
        if (file.eof())
            break;

        // check if an error happened while reading from the file
        if (!file)
        {
            std::cerr << "Error while reading from the model configuration file '" << strFilename << "'." << std::endl;
            return false;
        }

        // find the first non-whitespace character
        std::string::size_type pos;
        pos = strBuffer.find_first_not_of(" \t");

        // check for empty lines
        if ((pos == std::string::npos) || (strBuffer[pos] == '\n') || (strBuffer[pos] == '\r') || (strBuffer[pos] == 0))
            continue;

        // check for comment lines
        if (strBuffer[pos] == '#')
            continue;

        // get the key
        std::string strKey;
        strKey = strBuffer.substr(pos, strBuffer.find_first_of(" =\t\n\r", pos) - pos);
        pos += strKey.size();

        // get the '=' character
        pos = strBuffer.find_first_not_of(" \t", pos);
        if ((pos == std::string::npos) || (strBuffer[pos] != '='))
        {
            std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
            return false;
        }

        // find the first non-whitespace character after the '=' character
        pos = strBuffer.find_first_not_of(" \t", pos + 1);

        // get the data
        std::string strData;
        strData = strBuffer.substr(pos, strBuffer.find_first_of("\n\r", pos) - pos);

        // handle the model creation
        if (strKey == "scale")
        {
            // set rendering scale factor
            m_renderScale = (float)atof(strData.c_str());
        }
        else if (strKey == "path")
        {
            // set the new path for the data files if one hasn't been set already
            if (m_path == "")
                strPath = strData;
        }
        else if (strKey == "skeleton")
        {
            // load core skeleton
            std::cout << "Loading skeleton '" << strData << "'..." << std::endl;
            if (!m_calCoreModel->loadCoreSkeleton(strPath + strData))
            {
                CalError::printLastError();
                return false;
            }
        }
        else if (strKey == "animation")
        {
            // load core animation
            std::cout << "Loading animation '" << strData << "'..." << std::endl;
            m_animationId[m_animationCount] = m_calCoreModel->loadCoreAnimation(strPath + strData);
            if (m_animationId[m_animationCount] == -1)
            {
                CalError::printLastError();
                return false;
            }

            m_animationCount++;
        }
        else if (strKey == "mesh")
        {
            // load core mesh
            std::cout << "Loading mesh '" << strData << "'..." << std::endl;
            if (m_calCoreModel->loadCoreMesh(strPath + strData) == -1)
            {
                CalError::printLastError();
                return false;
            }
        }
        else if (strKey == "material")
        {
            // load core material
            std::cout << "Loading material '" << strData << "'..." << std::endl;
            if (m_calCoreModel->loadCoreMaterial(strPath + strData) == -1)
            {
                CalError::printLastError();
                return false;
            }
        }
        else
        {
            std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
            return false;
        }
    }

    // explicitely close the file
    file.close();

    // load all textures and store the opengl texture id in the corresponding map in the material
    int materialId;
    for (materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
    {
        // get the core material
        CalCoreMaterial *pCoreMaterial;
        pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);

        // loop through all maps of the core material
        int mapId;
        for (mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
        {
            // get the filename of the texture
            std::string strFilename;
            strFilename = pCoreMaterial->getMapFilename(mapId);

            // load the texture from the file
            // GLuint textureId;
            // textureId = loadTexture(strPath + strFilename);

            // store the opengl texture id in the user data of the map
            // pCoreMaterial->setMapUserData(mapId, (Cal::UserData)textureId);
        }
    }

    // make one material thread for each material
    // NOTE: this is not the right way to do it, but this viewer can't do the right
    // mapping without further information on the model etc.
    for (materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
    {
        // create the a material thread
        m_calCoreModel->createCoreMaterialThread(materialId);

        // initialize the material thread
        m_calCoreModel->setCoreMaterialId(materialId, 0, materialId);
    }

    // Calculate Bounding Boxes

    m_calCoreModel->getCoreSkeleton()->calculateBoundingBoxes(m_calCoreModel);

    m_calModel = new CalModel(m_calCoreModel);

    // attach all meshes to the model
    int meshId;
    for (meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
    {
        m_calModel->attachMesh(meshId);
    }

    // set the material set of the whole model
    m_calModel->setMaterialSet(0);

    // set initial animation state
    m_state = 0;
    m_calModel->getMixer()->blendCycle(m_animationId[0], 1.0, 0.0f);

    return true;
}
//! load and parse the configuration file 
//! @param cf, configuration file name 
//! @return true on success, false otherwise 
bool CCal3DModelCache::parseModelConfiguration( const std::string& cf, const std::string& mediaPath )
{
    int animationCount = 0;

    std::string fn; 
    // open the model configuration file 
    std::ifstream file; 
    file.open( cf.c_str(), std::ios::in | std::ios::binary ); 
    if ( !file )
    {
      CONSOLE.addx( COLOR_ERROR, "Failed to open model configuration file '%s'.", cf.c_str() );
      return false;
    } 

    //CONSOLE.addx(  "Openiong model configuration file '%s'." ,cf.c_str() );

    // create a core model instance 
    m_calCoreModel = new CalCoreModel( "dummy" ); 
    //if(!m_calCoreModel->create("dummy")) 
    //{ 
    //   // "CalError : %s",CalError::getLastErrorDescription().c_str() 
    //   return false; 
    //} 

    // parse all lines from the model configuration file 
    int line; 
    for ( line = 1; ; line++ )
    {
      // read the next model configuration line 
      std::string strBuffer; 
      std::getline( file, strBuffer ); 

      // stop if we reached the end of file 
      if ( file.eof() )
      {
        break;
      } 

      // check if an error happend while reading from the file 
      if ( !file )
      {
        CONSOLE.addx( COLOR_ERROR, "Error while reading from the model configuration file '%s'.", cf.c_str() );
        return false;
      } 

      // find the first non-whitespace character 
      std::string::size_type pos; 
      pos = strBuffer.find_first_not_of( " \t" ); 

      // check for empty lines 
      if ( ( pos == std::string::npos ) || ( strBuffer[pos] == '\n' ) || ( strBuffer[pos] == '\r' ) || ( strBuffer[pos] == 0 ) )
      {
        continue;
      } 

      // check for comment lines 
      if ( strBuffer[pos] == '#' )
      {
        continue;
      } 

      // get the key 
      std::string strKey; 
      strKey = strBuffer.substr( pos, strBuffer.find_first_of( " =\t\n\r", pos ) - pos ); 
      pos += strKey.size(); 

      // get the '=' character 
      pos = strBuffer.find_first_not_of( " \t", pos ); 
      if ( ( pos == std::string::npos ) || ( strBuffer[pos] != '=' ) )
      {
        CONSOLE.addx( COLOR_ERROR, "%s  (%d): Invalid syntax.", cf.c_str(), line );
        return false;
      } 

      // find the first non-whitespace character after the '=' character 
      pos = strBuffer.find_first_not_of( " \t", pos + 1 ); 

      // get the data 
      std::string strData; 
      strData = strBuffer.substr( pos, strBuffer.find_first_of( "\n\r", pos ) - pos ); 

      //CONSOLE.addx( "CAL3D: %s", strKey.c_str() );

      // handle the model creation 
      if ( strKey == "scale" )
      {
        // set rendering scale factor 
        m_scale = float( atof( strData.c_str() ) );
      }
      else if ( strKey == "skeleton" )
      {
        // load core skeleton 
        fn.clear(); fn = mediaPath + "/" + strData; 

        fn = APP.useFile( fn.c_str() ).c_str();
        if ( APP.DebugMode )
        {
          CONSOLE.addx( "Loading skeleton '%s'...", fn.c_str() );
        }

        //"Loading skeleton '%s'...",fn.c_str() 
        if ( !m_calCoreModel->loadCoreSkeleton( fn ) )
        {
          CONSOLE.addx( COLOR_ERROR, "CalError (skeleton) : %s", CalError::getLastErrorDescription().c_str() );
          return false;
        }
      }
      else if ( strKey == "animation" )
      {
        //fn.clear(); fn=mediaPath+"/"+strData; 
        //// load core animation 
        ////"Loading animation '%s'...",fn.c_str() 
        //if(m_calCoreModel->loadCoreAnimation(fn) == -1) 
        //{ 
        //    //"CalError : %s",CalError::getLastErrorDescription().c_str() 
        //    return false; 
        //} 

        fn.clear(); fn = mediaPath + "/" + strData; 
        //CONSOLE.addx( "Loading animation '%s'...",fn.c_str() );
        fn = APP.useFile( fn.c_str() ).c_str();
        if ( APP.DebugMode )
        {
          CONSOLE.addx( "Loading animation '%s'...", fn.c_str() );
        }
        // load core mesh 
        //if (APP.DebugMode)
        //  CONSOLE.addx( "Loading mesh '%s'...",fn.c_str() );
        if ( animationCount > 255 )
        {
          return false;
        }
        m_animationId[animationCount] = m_calCoreModel->loadCoreAnimation( fn );
        if ( m_animationId[animationCount] == -1 )
        {
          CONSOLE.addx( COLOR_ERROR, "CalError (animation): %s", CalError::getLastErrorDescription().c_str() );
          return false;
        } 
        animationCount++;
      }
      else if ( strKey == "mesh" )
      {
        fn.clear(); fn = mediaPath + "/" + strData;

        fn = APP.useFile( fn.c_str() ).c_str();
        if ( APP.DebugMode )
        {
          CONSOLE.addx( "Loading mesh '%s'...", fn.c_str() );
        }

        // load core mesh
        if ( m_calCoreModel->loadCoreMesh( fn ) == -1 )
        {
          return false;
        }
      }
      else if ( strKey == "material" )
      {
        fn.clear(); fn = mediaPath + "/" + strData; 
        fn = APP.useFile( fn.c_str() ).c_str();
        // load core material 
        if ( APP.DebugMode )
        {
          CONSOLE.addx( "Loading material '%s'...", fn.c_str() );
        }
        if ( m_calCoreModel->loadCoreMaterial( fn ) == -1 )
        {
          CONSOLE.addx( COLOR_ERROR, "CalError (material): %s", CalError::getLastErrorDescription().c_str() );
          return false;
        }
      }
      else
      {
        // everything else triggers an error message, but is ignored 
        CONSOLE.addx( COLOR_ERROR, "%s  (%d): Invalid syntax.", cf.c_str(), line );
      }
    } 

    // explicitely close the file 
    file.close(); 

    ////////////////////////////////

    m_calCoreModel->scale( m_scale ); 

    // make one material thread for each material 
    // NOTE: this is not the right way to do it, but this viewer can't do the right 
    // mapping without further information on the model etc., so this is the only 
    // thing we can do here. 
    for ( int materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++ )
    {
      // create the a material thread 
      m_calCoreModel->createCoreMaterialThread( materialId ); 

      // initialize the material thread 
      m_calCoreModel->setCoreMaterialId( materialId, 0, materialId );
    } 

    m_calCoreModel->getCoreSkeleton()->calculateBoundingBoxes( m_calCoreModel ); 

    // load all textures and store the texture id in the corresponding map in the material 
    for ( int materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++ )
    {
      // get the core material 
      CalCoreMaterial* pCoreMaterial; 
      pCoreMaterial = m_calCoreModel->getCoreMaterial( materialId ); 

      // loop through all maps of the core material 
      int mapId; 
      for ( mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++ )
      {
        // get the filename of the texture 
        std::string fn = mediaPath + "/" + pCoreMaterial->getMapFilename( mapId ); 

        // load the texture from the file 
        irr::video::ITexture* texture = IRR.smgr->getVideoDriver()->getTexture( APP.useFile( fn.c_str() ).c_str() ); 
        if ( texture )
        {
          // store the texture id in the user data of the map 
          pCoreMaterial->setMapUserData( mapId, ( Cal::UserData )texture );
        }
        else
        {
          //ok=false; 
          //"Loading texture '%s' failed.",fn.c_str() 
        }
      }
    } 

    return true;
}