

Public Member Functions | |
| AsciiModelLoader (istream &_in) | |
| virtual Model * | load () |
| Mesh::Material * | loadMaterial () |
| Mesh * | loadMesh () |
| Mesh::VertexDescription * | loadVertexDescription () |
| char * | loadVertices (const Mesh::VertexDescription &vertexDesc, uint32 &vertexCount) |
| virtual void | reportError (const string &) |
| ~AsciiModelLoader () | |
Private Attributes | |
| Tokenizer | tok |
<modelfile> ::= <header> <model>
<header> ::= #celmodel__ascii
<model> ::= { <material_definition> } { <mesh_definition> }
<material_definition> ::= material
{ <material_attribute> }
end_material
<texture_semantic> ::= texture0 |
normalmap |
specularmap |
emissivemap
<texture> ::= <texture_semantic> <string>
<material_attribute> ::= diffuse <color> |
specular <color> |
emissive <color> |
specpower <float> |
opacity <float> |
<texture>
<color> ::= <float> <float> <float>
<string> ::= """ { letter } """
<mesh_definition> ::= mesh
<vertex_description>
<vertex_pool>
{ <prim_group> }
end_mesh
<vertex_description> ::= vertexdesc
{ <vertex_attribute> }
end_vertexdesc
<vertex_attribute> ::= <vertex_semantic> <vertex_format>
<vertex_semantic> ::= position | normal | color0 | color1 | tangent |
texcoord0 | texcoord1 | texcoord2 | texcoord3
<vertex_format> ::= f1 | f2 | f3 | f4 | ub4
<vertex_pool> ::= vertices <count>
{ <float> }
<count> ::= <unsigned_int>
<prim_group> ::= <prim_group_type> <material_index> <count>
{ <unsigned_int> }
<prim_group_type> ::= trilist | tristrip | trifan |
linelist | linestrip | points
<material_index> :: <unsigned_int> | -1
Definition at line 95 of file modelfile.cpp.
|
|
Definition at line 286 of file modelfile.cpp. 00286 : 00287 tok(&_in) 00288 { 00289 }
|
|
|
Definition at line 292 of file modelfile.cpp. 00293 {
00294 }
|
|
|
Implements ModelLoader. Definition at line 676 of file modelfile.cpp. References Model::addMaterial(), Model::addMesh(), Tokenizer::getNameValue(), loadMaterial(), loadMesh(), Tokenizer::nextToken(), Tokenizer::pushBack(), reportError(), and tok. 00677 {
00678 Model* model = new Model();
00679 bool seenMeshes = false;
00680
00681 if (model == NULL)
00682 {
00683 reportError("Unable to allocate memory for model");
00684 return NULL;
00685 }
00686
00687 // Parse material and mesh definitions
00688 for (;;)
00689 {
00690 Tokenizer::TokenType ttype = tok.nextToken();
00691
00692 if (ttype == Tokenizer::TokenEnd)
00693 {
00694 break;
00695 }
00696 else if (ttype == Tokenizer::TokenName)
00697 {
00698 string name = tok.getNameValue();
00699 tok.pushBack();
00700
00701 if (name == "material")
00702 {
00703 if (seenMeshes)
00704 {
00705 reportError("Materials must be defined before meshes");
00706 delete model;
00707 return NULL;
00708 }
00709
00710 Mesh::Material* material = loadMaterial();
00711 if (material == NULL)
00712 {
00713 delete model;
00714 return NULL;
00715 }
00716
00717 model->addMaterial(material);
00718 }
00719 else if (name == "mesh")
00720 {
00721 seenMeshes = true;
00722
00723 Mesh* mesh = loadMesh();
00724 if (mesh == NULL)
00725 {
00726 delete model;
00727 return NULL;
00728 }
00729
00730 model->addMesh(mesh);
00731 }
00732 else
00733 {
00734 reportError(string("Error: Unknown block type ") + name);
00735 delete model;
00736 return NULL;
00737 }
00738 }
00739 else
00740 {
00741 reportError("Block name expected");
00742 return NULL;
00743 }
00744 }
00745
00746 return model;
00747 }
|
|
|
Definition at line 307 of file modelfile.cpp. References DefaultDiffuse(), DefaultEmissive(), DefaultOpacity, DefaultSpecular(), DefaultSpecularPower, Mesh::Material::diffuse, Mesh::Material::emissive, ResourceManager< T >::getHandle(), Tokenizer::getNameValue(), Tokenizer::getNumberValue(), Tokenizer::getStringValue(), GetTextureManager(), ModelLoader::getTexturePath(), Tokenizer::getTokenType(), Mesh::Material::maps, Tokenizer::nextToken(), Mesh::Material::opacity, Mesh::parseTextureSemantic(), reportError(), Mesh::Material::specular, Mesh::Material::specularPower, and tok. Referenced by load(). 00308 {
00309 if (tok.nextToken() != Tokenizer::TokenName ||
00310 tok.getNameValue() != "material")
00311 {
00312 reportError("Material definition expected");
00313 return NULL;
00314 }
00315
00316 Mesh::Material* material = new Mesh::Material();
00317
00318 material->diffuse = DefaultDiffuse;
00319 material->specular = DefaultSpecular;
00320 material->emissive = DefaultEmissive;
00321 material->specularPower = DefaultSpecularPower;
00322 material->opacity = DefaultOpacity;
00323
00324 while (tok.nextToken() == Tokenizer::TokenName &&
00325 tok.getNameValue() != "end_material")
00326 {
00327 string property = tok.getNameValue();
00328 Mesh::TextureSemantic texType = Mesh::parseTextureSemantic(property);
00329
00330 if (texType != Mesh::InvalidTextureSemantic)
00331 {
00332 if (tok.nextToken() != Tokenizer::TokenString)
00333 {
00334 reportError("Texture name expected");
00335 delete material;
00336 return NULL;
00337 }
00338
00339 ResourceHandle tex = GetTextureManager()->getHandle(TextureInfo(tok.getStringValue(), getTexturePath(), TextureInfo::WrapTexture));
00340
00341 material->maps[texType] = tex;
00342 }
00343 else
00344 {
00345 // All non-texture material properties are 3-vectors except
00346 // specular power and opacity
00347 double data[3];
00348 int nValues = 3;
00349 if (property == "specpower" || property == "opacity")
00350 nValues = 1;
00351
00352 for (int i = 0; i < nValues; i++)
00353 {
00354 if (tok.nextToken() != Tokenizer::TokenNumber)
00355 {
00356 reportError("Bad property value in material");
00357 delete material;
00358 return NULL;
00359 }
00360 data[i] = tok.getNumberValue();
00361 }
00362
00363 Color colorVal;
00364 if (nValues == 3)
00365 colorVal = Color((float) data[0], (float) data[1], (float) data[2]);
00366
00367 if (property == "diffuse")
00368 material->diffuse = colorVal;
00369 else if (property == "specular")
00370 material->specular = colorVal;
00371 else if (property == "emissive")
00372 material->emissive = colorVal;
00373 else if (property == "opacity")
00374 material->opacity = (float) data[0];
00375 else if (property == "specpower")
00376 material->specularPower = (float) data[0];
00377 }
00378 }
00379
00380 if (tok.getTokenType() != Tokenizer::TokenName)
00381 {
00382 delete material;
00383 return NULL;
00384 }
00385 else
00386 {
00387 return material;
00388 }
00389 }
|
|
|
Definition at line 582 of file modelfile.cpp. References Mesh::addGroup(), Tokenizer::getNameValue(), Tokenizer::getNumberValue(), loadVertexDescription(), loadVertices(), Tokenizer::nextToken(), Mesh::parsePrimitiveGroupType(), reportError(), Mesh::setVertexDescription(), Mesh::setVertices(), and tok. Referenced by load(). 00583 {
00584 if (tok.nextToken() != Tokenizer::TokenName ||
00585 tok.getNameValue() != "mesh")
00586 {
00587 reportError("Mesh definition expected");
00588 return NULL;
00589 }
00590
00591 Mesh::VertexDescription* vertexDesc = loadVertexDescription();
00592 if (vertexDesc == NULL)
00593 return NULL;
00594
00595 uint32 vertexCount = 0;
00596 char* vertexData = loadVertices(*vertexDesc, vertexCount);
00597 if (vertexData == NULL)
00598 return NULL;
00599
00600 Mesh* mesh = new Mesh();
00601 mesh->setVertexDescription(*vertexDesc);
00602 mesh->setVertices(vertexCount, vertexData);
00603
00604 while (tok.nextToken() == Tokenizer::TokenName &&
00605 tok.getNameValue() != "end_mesh")
00606 {
00607 Mesh::PrimitiveGroupType type =
00608 Mesh::parsePrimitiveGroupType(tok.getNameValue());
00609 if (type == Mesh::InvalidPrimitiveGroupType)
00610 {
00611 reportError("Bad primitive group type: " + tok.getNameValue());
00612 delete mesh;
00613 return NULL;
00614 }
00615
00616 if (tok.nextToken() != Tokenizer::TokenNumber)
00617 {
00618 reportError("Material index expected in primitive group");
00619 delete mesh;
00620 return NULL;
00621 }
00622
00623 uint32 materialIndex;
00624 if (tok.getNumberValue() == -1.0)
00625 materialIndex = ~0;
00626 else
00627 materialIndex = (uint32) tok.getNumberValue();
00628
00629 if (tok.nextToken() != Tokenizer::TokenNumber)
00630 {
00631 reportError("Index count expected in primitive group");
00632 delete mesh;
00633 return NULL;
00634 }
00635
00636 uint32 indexCount = (uint32) tok.getNumberValue();
00637
00638 uint32* indices = new uint32[indexCount];
00639 if (indices == NULL)
00640 {
00641 reportError("Not enough memory to hold indices");
00642 delete mesh;
00643 return NULL;
00644 }
00645
00646 for (uint32 i = 0; i < indexCount; i++)
00647 {
00648 if (tok.nextToken() != Tokenizer::TokenNumber)
00649 {
00650 reportError("Incomplete index list in primitive group");
00651 delete indices;
00652 delete mesh;
00653 return NULL;
00654 }
00655
00656 uint32 index = (uint32) tok.getNumberValue();
00657 if (index >= vertexCount)
00658 {
00659 reportError("Index out of range");
00660 delete indices;
00661 delete mesh;
00662 return NULL;
00663 }
00664
00665 indices[i] = index;
00666 }
00667
00668 mesh->addGroup(type, materialIndex, indexCount, indices);
00669 }
00670
00671 return mesh;
00672 }
|
|
|
Definition at line 393 of file modelfile.cpp. References Mesh::VertexAttribute::format, Tokenizer::getNameValue(), Tokenizer::getTokenType(), Mesh::getVertexAttributeSize(), Tokenizer::nextToken(), Mesh::VertexAttribute::offset, Mesh::parseVertexAttributeFormat(), Mesh::parseVertexAttributeSemantic(), reportError(), Mesh::VertexAttribute::semantic, and tok. Referenced by loadMesh(). 00394 {
00395 if (tok.nextToken() != Tokenizer::TokenName ||
00396 tok.getNameValue() != "vertexdesc")
00397 {
00398 reportError("Vertex description expected");
00399 return NULL;
00400 }
00401
00402 int maxAttributes = 16;
00403 int nAttributes = 0;
00404 uint32 offset = 0;
00405 Mesh::VertexAttribute* attributes = new Mesh::VertexAttribute[maxAttributes];
00406
00407 while (tok.nextToken() == Tokenizer::TokenName &&
00408 tok.getNameValue() != "end_vertexdesc")
00409 {
00410 string semanticName;
00411 string formatName;
00412 bool valid = false;
00413
00414 if (nAttributes == maxAttributes)
00415 {
00416 // TODO: Should eliminate the attribute limit, though no real vertex
00417 // will ever exceed it.
00418 reportError("Attribute limit exceeded in vertex description");
00419 delete[] attributes;
00420 return NULL;
00421 }
00422
00423 semanticName = tok.getNameValue();
00424
00425 if (tok.nextToken() == Tokenizer::TokenName)
00426 {
00427 formatName = tok.getNameValue();
00428 valid = true;
00429 }
00430
00431 if (!valid)
00432 {
00433 reportError("Invalid vertex description");
00434 delete[] attributes;
00435 return NULL;
00436 }
00437
00438 Mesh::VertexAttributeSemantic semantic =
00439 Mesh::parseVertexAttributeSemantic(semanticName);
00440 if (semantic == Mesh::InvalidSemantic)
00441 {
00442 reportError(string("Invalid vertex attribute semantic '") +
00443 semanticName + "'");
00444 delete[] attributes;
00445 return NULL;
00446 }
00447
00448 Mesh::VertexAttributeFormat format =
00449 Mesh::parseVertexAttributeFormat(formatName);
00450 if (format == Mesh::InvalidFormat)
00451 {
00452 reportError(string("Invalid vertex attribute format '") +
00453 formatName + "'");
00454 delete[] attributes;
00455 return NULL;
00456 }
00457
00458 attributes[nAttributes].semantic = semantic;
00459 attributes[nAttributes].format = format;
00460 attributes[nAttributes].offset = offset;
00461
00462 offset += Mesh::getVertexAttributeSize(format);
00463 nAttributes++;
00464 }
00465
00466 if (tok.getTokenType() != Tokenizer::TokenName)
00467 {
00468 reportError("Invalid vertex description");
00469 delete[] attributes;
00470 return NULL;
00471 }
00472
00473 if (nAttributes == 0)
00474 {
00475 reportError("Vertex definitition cannot be empty");
00476 delete[] attributes;
00477 return NULL;
00478 }
00479
00480 return new Mesh::VertexDescription(offset, nAttributes, attributes);
00481 }
|
|
||||||||||||
|
Definition at line 485 of file modelfile.cpp. References Tokenizer::getNameValue(), Tokenizer::getNumberValue(), Mesh::getVertexAttributeSize(), Tokenizer::nextToken(), reportError(), and tok. Referenced by loadMesh(). 00487 {
00488 if (tok.nextToken() != Tokenizer::TokenName ||
00489 tok.getNameValue() != "vertices")
00490 {
00491 reportError("Vertex data expected");
00492 return NULL;
00493 }
00494
00495 if (tok.nextToken() != Tokenizer::TokenNumber)
00496 {
00497 reportError("Vertex count expected");
00498 return NULL;
00499 }
00500
00501 double num = tok.getNumberValue();
00502 if (num != floor(num) || num <= 0.0)
00503 {
00504 reportError("Bad vertex count for mesh");
00505 return NULL;
00506 }
00507
00508 vertexCount = (uint32) num;
00509 uint32 vertexDataSize = vertexDesc.stride * vertexCount;
00510 char* vertexData = new char[vertexDataSize];
00511 if (vertexData == NULL)
00512 {
00513 reportError("Not enough memory to hold vertex data");
00514 return NULL;
00515 }
00516
00517 uint32 offset = 0;
00518 double data[4];
00519 for (uint32 i = 0; i < vertexCount; i++, offset += vertexDesc.stride)
00520 {
00521 assert(offset < vertexDataSize);
00522 for (uint32 attr = 0; attr < vertexDesc.nAttributes; attr++)
00523 {
00524 Mesh::VertexAttributeFormat fmt = vertexDesc.attributes[attr].format;
00525 uint32 nBytes = Mesh::getVertexAttributeSize(fmt);
00526 int readCount = 0;
00527 switch (fmt)
00528 {
00529 case Mesh::Float1:
00530 readCount = 1;
00531 break;
00532 case Mesh::Float2:
00533 readCount = 2;
00534 break;
00535 case Mesh::Float3:
00536 readCount = 3;
00537 break;
00538 case Mesh::Float4:
00539 case Mesh::UByte4:
00540 readCount = 4;
00541 break;
00542 default:
00543 assert(0);
00544 delete[] vertexData;
00545 return NULL;
00546 }
00547
00548 for (int j = 0; j < readCount; j++)
00549 {
00550 if (tok.nextToken() != Tokenizer::TokenNumber)
00551 {
00552 reportError("Error in vertex data");
00553 delete[] vertexData;
00554 }
00555 data[j] = tok.getNumberValue();
00556
00557 // TODO: range check unsigned byte values
00558 }
00559
00560 uint32 base = offset + vertexDesc.attributes[attr].offset;
00561 if (fmt == Mesh::UByte4)
00562 {
00563 for (int k = 0; k < readCount; k++)
00564 {
00565 reinterpret_cast<unsigned char*>(vertexData + base)[k] =
00566 (unsigned char) (data[k]);
00567 }
00568 }
00569 else
00570 {
00571 for (int k = 0; k < readCount; k++)
00572 reinterpret_cast<float*>(vertexData + base)[k] = (float) data[k];
00573 }
00574 }
00575 }
00576
00577 return vertexData;
00578 }
|
|
|
Definition at line 298 of file modelfile.cpp. References Tokenizer::getLineNumber(), ModelLoader::reportError(), and tok. Referenced by load(), loadMaterial(), loadMesh(), loadVertexDescription(), and loadVertices(). 00299 {
00300 char buf[32];
00301 sprintf(buf, " (line %d)", tok.getLineNumber());
00302 ModelLoader::reportError(msg + string(buf));
00303 }
|
|
|
Definition at line 111 of file modelfile.cpp. Referenced by load(), loadMaterial(), loadMesh(), loadVertexDescription(), loadVertices(), and reportError(). |
1.4.1