Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

BinaryModelLoader Class Reference

Inheritance diagram for BinaryModelLoader:

Inheritance graph
Collaboration diagram for BinaryModelLoader:

Collaboration graph
List of all members.

Public Member Functions

 BinaryModelLoader (istream &_in)
virtual Modelload ()
Mesh::MaterialloadMaterial ()
MeshloadMesh ()
Mesh::VertexDescriptionloadVertexDescription ()
char * loadVertices (const Mesh::VertexDescription &vertexDesc, uint32 &vertexCount)
virtual void reportError (const string &)
 ~BinaryModelLoader ()

Private Attributes

istream & in

Constructor & Destructor Documentation

BinaryModelLoader::BinaryModelLoader istream &  _in  ) 
 

Definition at line 1050 of file modelfile.cpp.

01050                                                  :
01051     in(_in)
01052 {
01053 }

BinaryModelLoader::~BinaryModelLoader  ) 
 

Definition at line 1056 of file modelfile.cpp.

01057 {
01058 }


Member Function Documentation

Model * BinaryModelLoader::load  )  [virtual]
 

Implements ModelLoader.

Definition at line 1201 of file modelfile.cpp.

References Model::addMaterial(), Model::addMesh(), CMOD_Material, CMOD_Mesh, in, loadMaterial(), loadMesh(), readToken(), and reportError().

01202 {
01203     Model* model = new Model();
01204     bool seenMeshes = false;
01205 
01206     if (model == NULL)
01207     {
01208         reportError("Unable to allocate memory for model");
01209         return NULL;
01210     }
01211 
01212     // Parse material and mesh definitions
01213     for (;;)
01214     {
01215         ModelFileToken tok = readToken(in);
01216 
01217         if (in.eof())
01218         {
01219             break;
01220         }
01221         else if (tok == CMOD_Material)
01222         {
01223             if (seenMeshes)
01224             {
01225                 reportError("Materials must be defined before meshes");
01226                 delete model;
01227                 return NULL;
01228             }
01229 
01230             Mesh::Material* material = loadMaterial();
01231             if (material == NULL)
01232             {
01233                 delete model;
01234                 return NULL;
01235             }
01236 
01237             model->addMaterial(material);
01238         }
01239         else if (tok == CMOD_Mesh)
01240         {
01241             seenMeshes = true;
01242 
01243             Mesh* mesh = loadMesh();
01244             if (mesh == NULL)
01245             {
01246                 delete model;
01247                 return NULL;
01248             }
01249 
01250             model->addMesh(mesh);
01251         }
01252         else
01253         {
01254             reportError("Error: Unknown block type in model");
01255             delete model;
01256             return NULL;
01257         }
01258     }
01259      
01260     return model;
01261 }

Mesh::Material * BinaryModelLoader::loadMaterial  ) 
 

Definition at line 1265 of file modelfile.cpp.

References CMOD_Diffuse, CMOD_Emissive, CMOD_EndMaterial, CMOD_Opacity, CMOD_Specular, CMOD_SpecularPower, CMOD_Texture, DefaultDiffuse(), DefaultEmissive(), DefaultOpacity, DefaultSpecular(), DefaultSpecularPower, Mesh::Material::diffuse, Mesh::Material::emissive, ResourceManager< T >::getHandle(), GetTextureManager(), ModelLoader::getTexturePath(), ignoreValue(), in, Mesh::Material::maps, Mesh::Material::opacity, readInt16(), readToken(), readTypeColor(), readTypeFloat1(), readTypeString(), reportError(), Mesh::Material::specular, and Mesh::Material::specularPower.

Referenced by load().

01266 {
01267     Mesh::Material* material = new Mesh::Material();
01268 
01269     material->diffuse = DefaultDiffuse;
01270     material->specular = DefaultSpecular;
01271     material->emissive = DefaultEmissive;
01272     material->specularPower = DefaultSpecularPower;
01273     material->opacity = DefaultOpacity;
01274 
01275     for (;;)
01276     {
01277         ModelFileToken tok = readToken(in);
01278         switch (tok)
01279         {
01280         case CMOD_Diffuse:
01281             if (!readTypeColor(in, material->diffuse))
01282             {
01283                 reportError("Incorrect type for diffuse color");
01284                 delete material;
01285                 return NULL;
01286             }
01287             break;
01288 
01289         case CMOD_Specular:
01290             if (!readTypeColor(in, material->specular))
01291             {
01292                 reportError("Incorrect type for specular color");
01293                 delete material;
01294                 return NULL;
01295             }
01296             break;
01297 
01298         case CMOD_Emissive:
01299             if (!readTypeColor(in, material->emissive))
01300             {
01301                 reportError("Incorrect type for emissive color");
01302                 delete material;
01303                 return NULL;
01304             }
01305             break;
01306 
01307         case CMOD_SpecularPower:
01308             if (!readTypeFloat1(in, material->specularPower))
01309             {
01310                 reportError("Float expected for specularPower");
01311                 delete material;
01312                 return NULL;
01313             }
01314             break;
01315 
01316         case CMOD_Opacity:
01317             if (!readTypeFloat1(in, material->opacity))
01318             {
01319                 reportError("Float expected for opacity");
01320                 delete material;
01321                 return NULL;
01322             }
01323             break;
01324 
01325         case CMOD_Texture:
01326             {
01327                 int16 texType = readInt16(in);
01328                 if (texType < 0 || texType >= Mesh::TextureSemanticMax)
01329                 {
01330                     reportError("Bad texture type");
01331                     delete material;
01332                     return NULL;
01333                 }
01334 
01335                 string texfile;
01336                 if (!readTypeString(in, texfile))
01337                 {
01338                     reportError("String expected for texture filename");
01339                     delete material;
01340                     return NULL;
01341                 }
01342 
01343                 if (texfile.empty())
01344                 {
01345                     reportError("Zero length texture name in material definition");
01346                     delete material;
01347                     return NULL;
01348                 }
01349 
01350                 ResourceHandle tex = GetTextureManager()->getHandle(TextureInfo(texfile, getTexturePath(), TextureInfo::WrapTexture));
01351                 
01352                 material->maps[texType] = tex;
01353             }
01354             break;
01355             
01356         case CMOD_EndMaterial:
01357             return material;
01358 
01359         default:
01360             // Skip unrecognized tokens
01361             if (!ignoreValue(in))
01362             {
01363                 delete material;
01364                 return NULL;
01365             }
01366         } // switch
01367     } // for
01368 }

Mesh * BinaryModelLoader::loadMesh  ) 
 

Definition at line 1441 of file modelfile.cpp.

References Mesh::addGroup(), CMOD_EndMesh, in, loadVertexDescription(), loadVertices(), readInt16(), readUint(), reportError(), Mesh::setVertexDescription(), and Mesh::setVertices().

Referenced by load().

01442 {
01443     Mesh::VertexDescription* vertexDesc = loadVertexDescription();
01444     if (vertexDesc == NULL)
01445         return NULL;
01446 
01447     uint32 vertexCount = 0;
01448     char* vertexData = loadVertices(*vertexDesc, vertexCount);
01449     if (vertexData == NULL)
01450         return NULL;
01451 
01452     Mesh* mesh = new Mesh();
01453     mesh->setVertexDescription(*vertexDesc);
01454     mesh->setVertices(vertexCount, vertexData);
01455 
01456     for (;;)
01457     {
01458         int16 tok = readInt16(in);
01459         
01460         if (tok == CMOD_EndMesh)
01461         {
01462             break;
01463         }
01464         else if (tok < 0 || tok >= Mesh::PrimitiveTypeMax)
01465         {
01466             reportError("Bad primitive group type");
01467             delete mesh;
01468             return NULL;
01469         }
01470 
01471         Mesh::PrimitiveGroupType type =
01472             static_cast<Mesh::PrimitiveGroupType>(tok);
01473         uint32 materialIndex = readUint(in);
01474         uint32 indexCount = readUint(in);
01475 
01476         uint32* indices = new uint32[indexCount];
01477         if (indices == NULL)
01478         {
01479             reportError("Not enough memory to hold indices");
01480             delete mesh;
01481             return NULL;
01482         }
01483 
01484         for (uint32 i = 0; i < indexCount; i++)
01485         {
01486             uint32 index = readUint(in);
01487             if (index >= vertexCount)
01488             {
01489                 reportError("Index out of range");
01490                 delete indices;
01491                 delete mesh;
01492                 return NULL;
01493             }
01494 
01495             indices[i] = index;
01496         }
01497 
01498         mesh->addGroup(type, materialIndex, indexCount, indices);
01499     }
01500 
01501     return mesh;
01502 }

Mesh::VertexDescription * BinaryModelLoader::loadVertexDescription  ) 
 

Definition at line 1372 of file modelfile.cpp.

References CMOD_EndVertexDesc, CMOD_VertexDesc, Mesh::VertexAttribute::format, Mesh::getVertexAttributeSize(), in, Mesh::VertexAttribute::offset, readInt16(), readToken(), reportError(), and Mesh::VertexAttribute::semantic.

Referenced by loadMesh().

01373 {
01374     if (readToken(in) != CMOD_VertexDesc)
01375     {
01376         reportError("Vertex description expected");
01377         return NULL;
01378     }
01379 
01380     int maxAttributes = 16;
01381     int nAttributes = 0;
01382     uint32 offset = 0;
01383     Mesh::VertexAttribute* attributes = new Mesh::VertexAttribute[maxAttributes];
01384 
01385     for (;;)
01386     {
01387         int16 tok = readInt16(in);
01388         
01389         if (tok == CMOD_EndVertexDesc)
01390         {
01391             break;
01392         }
01393         else if (tok >= 0 && tok < Mesh::SemanticMax)
01394         {
01395             int16 fmt = readInt16(in);
01396             if (fmt < 0 || fmt >= Mesh::FormatMax)
01397             {
01398                 reportError("Invalid vertex attribute type");
01399                 delete[] attributes;
01400                 return NULL;
01401             }
01402             else
01403             {
01404                 if (nAttributes == maxAttributes)
01405                 {
01406                     reportError("Too many attributes in vertex description");
01407                     delete[] attributes;
01408                     return NULL;
01409                 }
01410 
01411                 attributes[nAttributes].semantic =
01412                     static_cast<Mesh::VertexAttributeSemantic>(tok);
01413                 attributes[nAttributes].format = 
01414                     static_cast<Mesh::VertexAttributeFormat>(fmt);
01415                 attributes[nAttributes].offset = offset;
01416 
01417                 offset += Mesh::getVertexAttributeSize(attributes[nAttributes].format);
01418                 nAttributes++;
01419             }
01420         }
01421         else
01422         {
01423             reportError("Invalid semantic in vertex description");
01424             delete[] attributes;
01425             return NULL;
01426         }
01427     }
01428 
01429     if (nAttributes == 0)
01430     {
01431         reportError("Vertex definitition cannot be empty");
01432         delete[] attributes;
01433         return NULL;
01434     }
01435 
01436     return new Mesh::VertexDescription(offset, nAttributes, attributes);
01437 }

char * BinaryModelLoader::loadVertices const Mesh::VertexDescription vertexDesc,
uint32 vertexCount
 

Definition at line 1506 of file modelfile.cpp.

References CMOD_Vertices, in, readFloat(), readToken(), readUint(), and reportError().

Referenced by loadMesh().

01508 {
01509     if (readToken(in) != CMOD_Vertices)
01510     {
01511         reportError("Vertex data expected");
01512         return NULL;
01513     }
01514 
01515     vertexCount = readUint(in);
01516     uint32 vertexDataSize = vertexDesc.stride * vertexCount;
01517     char* vertexData = new char[vertexDataSize];
01518     if (vertexData == NULL)
01519     {
01520         reportError("Not enough memory to hold vertex data");
01521         return NULL;
01522     }
01523 
01524     uint32 offset = 0;
01525 
01526     for (uint32 i = 0; i < vertexCount; i++, offset += vertexDesc.stride)
01527     {
01528         assert(offset < vertexDataSize);
01529         for (uint32 attr = 0; attr < vertexDesc.nAttributes; attr++)
01530         {
01531             uint32 base = offset + vertexDesc.attributes[attr].offset;
01532             Mesh::VertexAttributeFormat fmt = vertexDesc.attributes[attr].format;
01533             int readCount = 0;
01534             switch (fmt)
01535             {
01536             case Mesh::Float1:
01537                 reinterpret_cast<float*>(vertexData + base)[0] = readFloat(in);
01538                 break;
01539             case Mesh::Float2:
01540                 reinterpret_cast<float*>(vertexData + base)[0] = readFloat(in);
01541                 reinterpret_cast<float*>(vertexData + base)[1] = readFloat(in);
01542                 break;
01543             case Mesh::Float3:
01544                 reinterpret_cast<float*>(vertexData + base)[0] = readFloat(in);
01545                 reinterpret_cast<float*>(vertexData + base)[1] = readFloat(in);
01546                 reinterpret_cast<float*>(vertexData + base)[2] = readFloat(in);
01547                 break;
01548             case Mesh::Float4:
01549                 reinterpret_cast<float*>(vertexData + base)[0] = readFloat(in);
01550                 reinterpret_cast<float*>(vertexData + base)[1] = readFloat(in);
01551                 reinterpret_cast<float*>(vertexData + base)[2] = readFloat(in);
01552                 reinterpret_cast<float*>(vertexData + base)[3] = readFloat(in);
01553                 break;
01554             case Mesh::UByte4:
01555                 in.get(reinterpret_cast<char*>(vertexData + base), 4);
01556                 break;
01557             default:
01558                 assert(0);
01559                 delete[] vertexData;
01560                 return NULL;
01561             }
01562         }
01563     }
01564 
01565     return vertexData;
01566 }

void BinaryModelLoader::reportError const string  )  [virtual]
 

Definition at line 1062 of file modelfile.cpp.

References ModelLoader::reportError().

Referenced by load(), loadMaterial(), loadMesh(), loadVertexDescription(), and loadVertices().

01063 {
01064     char buf[32];
01065     sprintf(buf, " (offset %d)", 0);
01066     ModelLoader::reportError(msg + string(buf));
01067 }


Member Data Documentation

istream& BinaryModelLoader::in [private]
 

Definition at line 153 of file modelfile.cpp.

Referenced by load(), loadMaterial(), loadMesh(), loadVertexDescription(), and loadVertices().


The documentation for this class was generated from the following file:
Generated on Sat Jan 14 22:33:06 2006 for Celestia by  doxygen 1.4.1