00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics/InputOutput/TextSceneLoader.h"
00027 #include "Core/InputOutput/TextFileReader.h"
00028 #include "Core/InputOutput/StreamTokenizer.h"
00029 #include "Core/InputOutput/FilePath.h"
00030 #include "Core/Codec/Tga/TargaLoader.h"
00031
00032 #include "Graphics/Scene/Scene.h"
00033 #include "Graphics/Fog/Fog.h"
00034 #include "Graphics/Light/LightManager.h"
00035 #include "Graphics/SceneNode/SceneNodeManager.h"
00036 #include "Graphics/Model/ModelManager.h"
00037 #include "Graphics/Mesh/MeshManager.h"
00038 #include "Graphics/MeshData/MeshDataManager.h"
00039 #include "Graphics/Material/MaterialManager.h"
00040 #include "Graphics/Texture/TextureManager.h"
00041 #include "Graphics/Picture/PictureManager.h"
00042
00043 namespace Lamp{
00044
00045
00046
00047 TextSceneLoader::TextSceneLoader(){
00048 }
00049
00050
00051 TextSceneLoader::~TextSceneLoader(){
00052 }
00053
00054
00055 void TextSceneLoader::load(const String& filePath, Scene* scene){
00056 load(filePath, scene, scene->getRootNode());
00057 }
00058
00059
00060 void TextSceneLoader::load(const String& filePath, Scene* scene,
00061 SceneNode* rootNode){
00062 FilePath path(filePath);
00063 Assert(path.existFile());
00064 TextFileReader* textFileReader = new TextFileReader(filePath);
00065 load(textFileReader, scene, rootNode, path.getFolderPath());
00066 delete textFileReader;
00067 }
00068
00069
00070 void TextSceneLoader::load(TextReader* textReader, Scene* scene,
00071 const String& basePath){
00072 load(textReader, scene, scene->getRootNode(), basePath);
00073 }
00074
00075
00076 void TextSceneLoader::load(TextReader* textReader, Scene* scene,
00077 SceneNode* rootNode, const String& basePath){
00078
00079 basePath_ = basePath;
00080 tokenizer_ = new StreamTokenizer(textReader);
00081 scene_ = scene;
00082 rootNode_ = rootNode;
00083 sceneNodeManager_ = scene->getSceneNodeManager();
00084 lightManager_ = scene->getLightManager();
00085 modelManager_ = scene->getModelManager();
00086 meshManager_ = scene->getMeshManager();
00087 meshDataManager_ = scene->getMeshDataManager();
00088 materialManager_ = scene->getMaterialManager();
00089 textureManager_ = scene->getTextureManager();
00090 pictureManager_ = scene->getPictureManager();
00091
00092
00093 bool rootNodeEnabled = rootNode_->isEnabled();
00094 rootNode_->setEnabled(false);
00095
00096
00097 readHeader();
00098
00099 while(true){
00100
00101 if(!tokenizer_->nextToken()){ break; }
00102 String chunkName = tokenizer_->getToken();
00103 if(chunkName == "Fog"){
00104 readFog();
00105 }else if(chunkName == "SceneNode"){
00106 readSceneNodeList();
00107 }else if(chunkName == "Light"){
00108 readLightList();
00109 }else if(chunkName == "Model"){
00110 readModelList();
00111 }else if(chunkName == "Mesh"){
00112 readMeshList();
00113 }else if(chunkName == "MeshData"){
00114 readMeshDataList();
00115 }else if(chunkName == "Material"){
00116 readMaterialList();
00117 }else if(chunkName == "Texture"){
00118 readTextureList();
00119 }else if(chunkName == "Picture"){
00120 readPictureList();
00121 }else if(chunkName == "SceneNodeLink"){
00122 readSceneNodeLinkList();
00123 }else if(chunkName == "ModelLink"){
00124 readModelLinkList();
00125 }else if(chunkName == "MeshLink"){
00126 readMeshLinkList();
00127 }else if(chunkName == "MaterialLink"){
00128 readMaterialLinkList();
00129 }else if(chunkName == "TextureLink"){
00130 readTextureLinkList();
00131 }else{
00132 ErrorOut("TextSceneLoader::load() "
00133 "invalid chunk %s (line %d)",
00134 chunkName.getBytes(), tokenizer_->getLineNumber());
00135 }
00136 }
00137 delete tokenizer_;
00138
00139 rootNode_->setEnabled(rootNodeEnabled);
00140 }
00141
00142
00143 void TextSceneLoader::readHeader(){
00144 skipWord("Header");
00145 openChunk();
00146 skipWord("type");
00147 skipWord("LampTextSceneFormat");
00148 skipWord("version");
00149 skipWord("0_9_0");
00150 closeChunk();
00151 }
00152
00153
00154
00155
00156 void TextSceneLoader::readFog(){
00157 Fog* fog = scene_->getFog();
00158 openChunk();
00159
00160 skipWord("color");
00161 fog->setColor(readColor4c());
00162
00163 skipWord("mode");
00164 fog->setModeString(readToken("TextSceneLoader::readFog()"));
00165
00166 skipWord("density");
00167 fog->setDensity(readFloat());
00168
00169 skipWord("near");
00170 fog->setNear(readFloat());
00171
00172 skipWord("far");
00173 fog->setFar(readFloat());
00174
00175 skipWord("enabled");
00176 fog->setEnabled(readBool());
00177 closeChunk();
00178 }
00179
00180
00181
00182
00183 void TextSceneLoader::readSceneNodeList(){
00184 openChunk();
00185 while(true){
00186 String token = readToken("readSceneNodeList()");
00187 if(token == "}"){ break; }
00188
00189 openChunk();
00190 skipWord("type");
00191 String type = readToken("readSceneNodeList()");
00192 if(type == "Standard"){
00193 readSceneNode(token);
00194 }else if(type == "LOD"){
00195 readLODSceneNode(token);
00196 }else{
00197 ErrorOut("TextSceneLoader::readSceneNodeList() "
00198 "invalid type %s (line %d)",
00199 type.getBytes(), tokenizer_->getLineNumber());
00200 }
00201 closeChunk();
00202 }
00203 }
00204
00205
00206 void TextSceneLoader::readSceneNode(const String& name){
00207 SceneNode* sceneNode = sceneNodeManager_->createSceneNode(name);
00208
00209 skipWord("scale");
00210 sceneNode->setScale(readVector3());
00211
00212 skipWord("rotation");
00213 sceneNode->setRotationXYZ(readVector3());
00214
00215 skipWord("translation");
00216 sceneNode->setTranslation(readVector3());
00217
00218 skipWord("enabled");
00219 sceneNode->setEnabled(readBool());
00220 }
00221
00222
00223 void TextSceneLoader::readLODSceneNode(const String& name){
00224 LODSceneNode* sceneNode = sceneNodeManager_->createLODSceneNode(name);
00225
00226 skipWord("scale");
00227 sceneNode->setScale(readVector3());
00228
00229 skipWord("rotation");
00230 sceneNode->setRotationXYZ(readVector3());
00231
00232 skipWord("translation");
00233 sceneNode->setTranslation(readVector3());
00234
00235 skipWord("enabled");
00236 sceneNode->setEnabled(readBool());
00237
00238 skipWord("lodThresholdCount");
00239 int lodThresholdCount = readInt();
00240 sceneNode->setLODThresholdCount(lodThresholdCount);
00241
00242 openChunk();
00243 for(int i = 0; i < lodThresholdCount; i++){
00244 sceneNode->setLODThreshold(i, readFloat());
00245 }
00246 closeChunk();
00247 }
00248
00249
00250
00251
00252 void TextSceneLoader::readLightList(){
00253 openChunk();
00254 while(true){
00255 String token = readToken("readLightList()");
00256 if(token == "}"){ break; }
00257
00258 openChunk();
00259 skipWord("type");
00260 String type = readToken("readLightList()");
00261 if(type == "Ambient"){
00262 readAmbientLight(token);
00263 }else if(type == "Directional"){
00264 readDirectionalLight(token);
00265 }else if(type == "Point"){
00266 readPointLight(token);
00267 }else{
00268 ErrorOut("TextSceneLoader::readLightList() "
00269 "invalid type %s (line %d)",
00270 type.getBytes(), tokenizer_->getLineNumber());
00271 }
00272 closeChunk();
00273 }
00274 }
00275
00276
00277 void TextSceneLoader::readLight(Light* light){
00278 skipWord("Light");
00279 openChunk();
00280
00281 skipWord("lightMask");
00282 light->setLightMask(readUInt());
00283
00284 skipWord("enabled");
00285 light->setEnabled(readBool());
00286 closeChunk();
00287 }
00288
00289
00290 void TextSceneLoader::readAmbientLight(const String& name){
00291 AmbientLight* light = lightManager_->createAmbientLight(name);
00292
00293 skipWord("color");
00294 light->setColor(readColor3f());
00295
00296 readLight(light);
00297 }
00298
00299
00300 void TextSceneLoader::readDirectionalLight(const String& name){
00301 DirectionalLight* light = lightManager_->createDirectionalLight(name);
00302
00303 skipWord("diffuse");
00304 light->setDiffuseColor(readColor3f());
00305
00306 skipWord("specular");
00307 light->setSpecularColor(readColor3f());
00308
00309 skipWord("direction");
00310 light->setDirection(readVector3());
00311
00312 readLight(light);
00313 }
00314
00315
00316 void TextSceneLoader::readPointLight(const String& name){
00317 PointLight* light = lightManager_->createPointLight(name);
00318
00319 skipWord("diffuse");
00320 light->setDiffuseColor(readColor3f());
00321
00322 skipWord("specular");
00323 light->setSpecularColor(readColor3f());
00324
00325 skipWord("position");
00326 light->setPosition(readVector3());
00327
00328 skipWord("range");
00329 light->setRange(readFloat());
00330
00331 skipWord("attenuation");
00332 Vector3 attenuation = readVector3();
00333 light->setAttenuation(attenuation.x, attenuation.y, attenuation.z);
00334
00335 readLight(light);
00336 }
00337
00338
00339
00340
00341 void TextSceneLoader::readModelList(){
00342 openChunk();
00343 while(true){
00344 String token = readToken("readModelList()");
00345 if(token == "}"){ break; }
00346
00347 openChunk();
00348 skipWord("type");
00349 String type = readToken("readModelList()");
00350 if(type == "Standard"){
00351 readStandardModel(token);
00352 }else if(type == "Character"){
00353 readCharacterModel(token);
00354 }else{
00355 ErrorOut("TextSceneLoader::readModelList() "
00356 "invalid type %s (line %d)",
00357 type.getBytes(), tokenizer_->getLineNumber());
00358 }
00359 closeChunk();
00360 }
00361 }
00362
00363
00364 void TextSceneLoader::readStandardModel(const String& name){
00365 StandardModel* model = modelManager_->createStandardModel(name);
00366
00367 skipWord("enabled");
00368 model->setEnabled(readBool());
00369 }
00370
00371
00372 void TextSceneLoader::readCharacterModel(const String& name){
00373 CharacterModel* model = modelManager_->createCharacterModel(name);
00374
00375 skipWord("enabled");
00376 model->setEnabled(readBool());
00377
00378 skipWord("bone");
00379 openChunk();
00380 while(true){
00381 String boneName = readToken("TextSceneLoader::readCharacterModel()");
00382 if(boneName == "}"){ break; }
00383 readBone(model, boneName);
00384 }
00385
00386 skipWord("boneLink");
00387 openChunk();
00388 while(true){
00389 String boneName = readToken("TextSceneLoader::readCharacterModel()");
00390 if(boneName == "}"){ break; }
00391 Bone* bone = model->searchBone(boneName);
00392 openChunk();
00393 while(true){
00394 String childName = readToken("TextSceneLoader::readCharacterModel()");
00395 if(childName == "}"){ break; }
00396 Bone* child = model->searchBone(childName);
00397 bone->addBone(child);
00398 }
00399 }
00400 }
00401
00402
00403 void TextSceneLoader::readBone(CharacterModel* model, const String& name){
00404 Bone* bone = model->createBone(name);
00405 openChunk();
00406
00407 skipWord("inversePoseMatrix");
00408 skipWord("Matrix34");
00409 bone->setInversePoseMatrix(readMatrix34());
00410
00411 skipWord("scale");
00412 bone->setScale(readVector3());
00413
00414 skipWord("rotation");
00415 bone->setRotationXYZ(readVector3());
00416
00417 skipWord("translation");
00418 bone->setTranslation(readVector3());
00419 closeChunk();
00420 }
00421
00422
00423
00424
00425 void TextSceneLoader::readMeshList(){
00426 openChunk();
00427 while(true){
00428 String token = readToken("readMeshList()");
00429 if(token == "}"){ break; }
00430
00431 openChunk();
00432 skipWord("type");
00433 String type = readToken("readMeshList()");
00434 if(type == "Rigid"){
00435 readRigidMesh(token);
00436 }else if(type == "Character"){
00437 readCharacterMesh(token);
00438 }else{
00439 ErrorOut("TextSceneLoader::readMeshList() "
00440 "invalid type %s (line %d)",
00441 type.getBytes(), tokenizer_->getLineNumber());
00442 }
00443 closeChunk();
00444 }
00445 }
00446
00447
00448 void TextSceneLoader::readRigidMesh(const String& name){
00449 RigidMesh* mesh = meshManager_->createRigidMesh(name);
00450
00451 skipWord("enabled");
00452 mesh->setEnabled(readBool());
00453 }
00454
00455
00456 void TextSceneLoader::readCharacterMesh(const String& name){
00457 CharacterMesh* mesh = meshManager_->createCharacterMesh(name);
00458
00459 skipWord("enabled");
00460 mesh->setEnabled(readBool());
00461 }
00462
00463
00464
00465
00466 void TextSceneLoader::readMeshDataList(){
00467 openChunk();
00468 while(true){
00469 String token = readToken("readMeshDataList()");
00470 if(token == "}"){ break; }
00471
00472 readMeshData(token);
00473 }
00474 }
00475
00476
00477 void TextSceneLoader::readMeshData(const String& name){
00478 MeshData* meshData = meshDataManager_->createMeshData(name);
00479 openChunk();
00480
00481 skipWord("boundingBox");
00482 meshData->setBoundingBox(readAxisAlignedBox());
00483
00484 skipWord("boundingSphere");
00485 meshData->setBoundingSphere(readSphere());
00486
00487 skipWord("primitiveType");
00488 String primitiveType = readToken("readMeshData()");
00489 meshData->setPrimitiveType(Mesh::primitiveTypeFromString(primitiveType));
00490
00491 if(meshData->hasVertexIndices()){
00492 skipWord("indices");
00493 int indexCount = readInt();
00494 meshData->setVertexIndexCount(indexCount);
00495 openChunk();
00496 for(int i = 0; i < indexCount; i++){
00497 meshData->setVertexIndex(i, readUShort());
00498 }
00499 closeChunk();
00500 }
00501
00502 skipWord("hasNormal");
00503 bool hasNormal = readBool();
00504 meshData->enableNormal(hasNormal);
00505
00506 skipWord("hasColor");
00507 bool hasColor = readBool();
00508 meshData->enableColor(hasColor);
00509
00510 skipWord("texCoordSetCount");
00511 int texCoordSetCount = readInt();
00512 meshData->setTexCoordSetCount(texCoordSetCount);
00513
00514 skipWord("texCoordType");
00515 int texCoordType[TexCoord::maxSetCount];
00516 for(int i = 0; i < texCoordSetCount; i++){
00517 texCoordType[i] = readInt();
00518 meshData->setTexCoordType(i, (TexCoord::Type)texCoordType[i]);
00519 }
00520
00521 skipWord("bonesPerVertex");
00522 int bonesPerVertex = readInt();
00523 meshData->setBonesPerVertex(bonesPerVertex);
00524 int weightsPerVertex = meshData->getWeightsPerVertex();
00525
00526 skipWord("vertices");
00527 int vertexCount = readInt();
00528 meshData->setVertexCount(vertexCount);
00529 openChunk();
00530 for(int i = 0; i < vertexCount; i++){
00531 int index = readInt();
00532 if(index != i){
00533 ErrorOut("TextSceneLoader::readMeshData() "
00534 "invalid index %d (line %d)",
00535 index, tokenizer_->getLineNumber());
00536 }
00537
00538 meshData->setPosition(i, readVector3());
00539
00540 if(hasNormal){ meshData->setNormal(i, readVector3()); }
00541
00542 if(hasColor){ meshData->setColor(i, readColor4c()); }
00543
00544 float texCoord[4];
00545 for(int j = 0; j < texCoordSetCount; j++){
00546 openChunk();
00547 for(int k = 0; k < texCoordType[j]; k++){
00548 texCoord[k] = readFloat();
00549 }
00550 closeChunk();
00551 meshData->setTexCoord(i, j, texCoord, texCoordType[j]);
00552 }
00553
00554 if(bonesPerVertex != 0){
00555 openChunk();
00556 for(int j = 0; j < bonesPerVertex; j++){
00557 meshData->setBoneIndex(i, j, readUChar());
00558 }
00559 closeChunk();
00560 }
00561
00562 if(weightsPerVertex != 0){
00563 openChunk();
00564 for(int j = 0; j < weightsPerVertex; j++){
00565 meshData->setWeight(i, j, readFloat());
00566 }
00567 closeChunk();
00568 }
00569 }
00570 closeChunk();
00571 closeChunk();
00572 }
00573
00574
00575
00576
00577 void TextSceneLoader::readMaterialList(){
00578 openChunk();
00579 while(true){
00580 String token = readToken("readMaterialList()");
00581 if(token == "}"){ break; }
00582
00583 openChunk();
00584 skipWord("type");
00585 String type = readToken("readMaterialList()");
00586 if(type == "Basic"){
00587 readBasicMaterial(token);
00588 }else{
00589 ErrorOut("TextSceneLoader::readMaterialList() "
00590 "invalid type %s (line %d)",
00591 type.getBytes(), tokenizer_->getLineNumber());
00592 }
00593 closeChunk();
00594 }
00595 }
00596
00597
00598 void TextSceneLoader::readMaterial(Material* material){
00599 skipWord("Material");
00600 openChunk();
00601
00602 skipWord("priority");
00603 material->setPriority(readInt());
00604
00605 skipWord("blendMode");
00606 String blendMode = readToken("readMaterial()");
00607 material->setBlendMode(Material::blendModeFromString(blendMode));
00608
00609 skipWord("alpha");
00610 material->setAlpha(readFloat());
00611
00612 skipWord("blendSource");
00613 String blendSource = readToken("readMaterial()");
00614 material->setBlendSource(Material::blendStateFromString(blendSource));
00615
00616 skipWord("blendDestination");
00617 String blendDestination = readToken("readMaterial()");
00618 material->setBlendDestination(
00619 Material::blendStateFromString(blendDestination));
00620
00621 skipWord("zWrite");
00622 material->setZWrite(readBool());
00623
00624 skipWord("zTest");
00625 material->setZTest(readBool());
00626
00627 skipWord("fogOption");
00628 String fogOption = readToken("readMaterial()");
00629 material->setFogOption(Material::fogOptionFromString(fogOption));
00630
00631 skipWord("lightMask");
00632 material->setLightMask(readUInt());
00633 closeChunk();
00634 }
00635
00636
00637 void TextSceneLoader::readBasicMaterial(const String& name){
00638 BasicMaterial* material = materialManager_->createBasicMaterial(name);
00639
00640 skipWord("baseUVIndex");
00641 material->setBaseUVIndex(readInt());
00642
00643 skipWord("glossUVIndex");
00644 material->setGlossUVIndex(readInt());
00645
00646 skipWord("lightUVIndex");
00647 material->setLightUVIndex(readInt());
00648
00649 skipWord("stainUVIndex");
00650 material->setStainUVIndex(readInt());
00651
00652
00653 skipWord("diffuseColor");
00654 material->setDiffuseColor(readColor3f());
00655
00656 skipWord("specularColor");
00657 material->setSpecularColor(readColor3f());
00658
00659 skipWord("specularPower");
00660 material->setSpecularPower(readFloat());
00661
00662 skipWord("ambientColor");
00663 material->setAmbientColor(readColor3f());
00664
00665 skipWord("emissiveColor");
00666 material->setEmissiveColor(readColor3f());
00667
00668 readMaterial(material);
00669 }
00670
00671
00672
00673
00674 void TextSceneLoader::readTextureList(){
00675 openChunk();
00676 while(true){
00677 String token = readToken("readTextureList()");
00678 if(token == "}"){ break; }
00679
00680 openChunk();
00681 skipWord("type");
00682 String type = readToken("readTextureList()");
00683 if(type == "Surface"){
00684 readSurfaceTexture(token);
00685 }else{
00686 ErrorOut("TextSceneLoader::readTextureList() "
00687 "invalid type %s (line %d)",
00688 type.getBytes(), tokenizer_->getLineNumber());
00689 }
00690 closeChunk();
00691 }
00692 }
00693
00694
00695 void TextSceneLoader::readSurfaceTexture(const String& name){
00696 SurfaceTexture* texture = textureManager_->createSurfaceTexture(name);
00697
00698 skipWord("addressModeU");
00699 String addressModeU = readToken("readSurfaceTexture()");
00700 texture->setAddressModeU(Texture::addressModeFromString(addressModeU));
00701
00702 skipWord("addressModeV");
00703 String addressModeV = readToken("readSurfaceTexture()");
00704 texture->setAddressModeV(Texture::addressModeFromString(addressModeV));
00705
00706 skipWord("repeatUV");
00707 texture->setRepeatUV(readTexCoord2());
00708
00709 skipWord("offsetUV");
00710 texture->setOffsetUV(readTexCoord2());
00711 }
00712
00713
00714
00715
00716 void TextSceneLoader::readPictureList(){
00717 openChunk();
00718 while(true){
00719 String token = readToken("readPictureList()");
00720 if(token == "}"){ break; }
00721 openChunk();
00722 skipWord("path");
00723 String path = readToken("readPictureList()");
00724 closeChunk();
00725
00726 FilePath filePath(path);
00727 String extension = filePath.getExtension();
00728
00729 Picture* picture;
00730 if(extension == "tga"){
00731 TargaLoader loader(basePath_ + path);
00732 loader.loadHeader();
00733
00734 if(loader.hasAlpha()){
00735 picture = readPictureRGBA8(token, loader);
00736 }else{
00737 picture = readPictureRGB8(token, loader);
00738 }
00739 }else{
00740 ErrorOut("TextSceneLoader::readPictureList() "
00741 "Unsupported picture format %s (line %d)",
00742 path.getBytes(), tokenizer_->getLineNumber());
00743 return;
00744 }
00745
00746 picture->setPath(path);
00747 }
00748 }
00749
00750
00751 Picture* TextSceneLoader::readPictureRGB8(
00752 const String& name, TargaLoader& loader){
00753 PictureRGB8* picture = pictureManager_->createPictureRGB8(name);
00754 picture->setSize(loader.getSize());
00755 loader.loadImage(picture->getImageBuffer());
00756 return picture;
00757 }
00758
00759
00760 Picture* TextSceneLoader::readPictureRGBA8(
00761 const String& name, TargaLoader& loader){
00762 PictureRGBA8* picture = pictureManager_->createPictureRGBA8(name);
00763 picture->setSize(loader.getSize());
00764 loader.loadImage(picture->getImageBuffer());
00765 return picture;
00766 }
00767
00768
00769
00770
00771 void TextSceneLoader::readSceneNodeLinkList(){
00772 openChunk();
00773 while(true){
00774 String token = readToken("readSceneNodeLinkList()");
00775 if(token == "}"){ break; }
00776 readSceneNodeLink(token);
00777 }
00778 }
00779
00780
00781 void TextSceneLoader::readSceneNodeLink(const String& name){
00782 SceneNode* sceneNode;
00783 if(name.equals("RootNode")){
00784 sceneNode = rootNode_;
00785 }else{
00786 sceneNode = sceneNodeManager_->search(name);
00787 if(sceneNode == NULL){
00788 ErrorOut("TextSceneLoader::readSceneNodeLink() "
00789 "not found sceneNode %s (line %d)",
00790 name.getBytes(), tokenizer_->getLineNumber());
00791 }
00792 }
00793
00794 openChunk();
00795 while(true){
00796 String token = readToken("readSceneNodeLink()");
00797 if(token == "}"){ break; }
00798 if(token == "SceneNode"){
00799
00800 openChunk();
00801 while(true){
00802 String subToken = readToken("readSceneNodeLink()");
00803 if(subToken == "}"){ break; }
00804 SceneNode* childNode = sceneNodeManager_->search(subToken);
00805 if(childNode == NULL){
00806 ErrorOut("TextSceneLoader::readSceneNodeLink() "
00807 "not found sceneNode %s (line %d)",
00808 subToken.getBytes(), tokenizer_->getLineNumber());
00809 }
00810 sceneNode->addSceneNode(childNode);
00811 }
00812 }else if(token == "SceneLeaf"){
00813
00814 openChunk();
00815 while(true){
00816 String subToken = readToken("readSceneNodeLink()");
00817 if(subToken == "}"){ break; }
00818 SceneLeaf* sceneLeaf = NULL;
00819 String sceneLeafName = readToken("readSceneNodeLink()");
00820 if(subToken.equals("Model")){
00821 sceneLeaf = modelManager_->search(sceneLeafName);
00822 }else if(subToken.equals("Light")){
00823 sceneLeaf = lightManager_->search(sceneLeafName);
00824 }else{
00825 ErrorOut("TextSceneLoader::readSceneNodeLink() "
00826 "unsupported type %s (line %d)",
00827 subToken.getBytes(), tokenizer_->getLineNumber());
00828 }
00829 if(sceneLeaf == NULL){
00830 ErrorOut("TextSceneLoader::readSceneNodeLink() "
00831 "not found sceneLeaf %s (line %d)",
00832 sceneLeafName.getBytes(), tokenizer_->getLineNumber());
00833 }
00834 sceneNode->addSceneLeaf(sceneLeaf);
00835 }
00836 }else{
00837 ErrorOut("TextSceneLoader::readSceneNodeLink() "
00838 "invalid token %s (line %d)",
00839 token.getBytes(), tokenizer_->getLineNumber());
00840 }
00841 }
00842 }
00843
00844
00845
00846
00847 void TextSceneLoader::readModelLinkList(){
00848 openChunk();
00849 while(true){
00850 String token = readToken("readModelLinkList()");
00851 if(token == "}"){ break; }
00852 readModelLink(token);
00853 }
00854 }
00855
00856
00857 void TextSceneLoader::readModelLink(const String& name){
00858 Model* model = modelManager_->search(name);
00859 if(model == NULL){
00860 ErrorOut("TextSceneLoader::readModelLink() "
00861 "not found model %s (line %d)",
00862 name.getBytes(), tokenizer_->getLineNumber());
00863 }
00864 openChunk();
00865 while(true){
00866 String token = readToken("readModelLink()");
00867 if(token == "}"){ break; }
00868
00869 Mesh* mesh = meshManager_->search(token);
00870 if(mesh == NULL){
00871 ErrorOut("TextSceneLoader::readModelLink() "
00872 "not found mesh %s (line %d)",
00873 token.getBytes(), tokenizer_->getLineNumber());
00874 }
00875 model->addMesh(mesh);
00876 }
00877 }
00878
00879
00880
00881
00882 void TextSceneLoader::readMeshLinkList(){
00883 openChunk();
00884 while(true){
00885 String token = readToken("readMeshLinkList()");
00886 if(token == "}"){ break; }
00887 readMeshLink(token);
00888 }
00889 }
00890
00891
00892 void TextSceneLoader::readMeshLink(const String& name){
00893 Mesh* mesh = meshManager_->search(name);
00894 if(mesh == NULL){
00895 ErrorOut("TextSceneLoader::readMeshLink() "
00896 "not found mesh %s (line %d)",
00897 name.getBytes(), tokenizer_->getLineNumber());
00898 }
00899 openChunk();
00900 while(true){
00901 String token = readToken("readMeshLink()");
00902 if(token == "}"){ break; }
00903 if(token == "MeshData"){
00904
00905 String subToken = readToken("readMeshLink()");
00906 MeshData* meshData = meshDataManager_->search(subToken);
00907 if(meshData == NULL){
00908 ErrorOut("TextSceneLoader::readMeshLink() "
00909 "not found meshData %s (line %d)",
00910 subToken.getBytes(), tokenizer_->getLineNumber());
00911 }
00912 mesh->setMeshData(meshData);
00913 }else if(token == "Material"){
00914
00915 String subToken = readToken("readMeshLink()");
00916 Material* material = materialManager_->search(subToken);
00917 if(material == NULL){
00918 ErrorOut("TextSceneLoader::readMeshLink() "
00919 "not found material %s (line %d)",
00920 subToken.getBytes(), tokenizer_->getLineNumber());
00921 }
00922 mesh->setMaterial(material);
00923 }else{
00924 ErrorOut("TextSceneLoader::readMeshLink() "
00925 "invalid token %s (line %d)",
00926 token.getBytes(), tokenizer_->getLineNumber());
00927 }
00928 }
00929 }
00930
00931
00932
00933
00934 void TextSceneLoader::readMaterialLinkList(){
00935 openChunk();
00936 while(true){
00937 String token = readToken("readMaterialLinkList()");
00938 if(token == "}"){ break; }
00939 openChunk();
00940 skipWord("type");
00941 String type = readToken("readMaterialLinkList()");
00942 if(type == "Basic"){
00943 readBasicMaterialLink(token);
00944 }else{
00945 ErrorOut("TextSceneLoader::readMaterialLinkList() "
00946 "invalid type %s (line %d)",
00947 type.getBytes(), tokenizer_->getLineNumber());
00948 }
00949 }
00950 }
00951
00952
00953 void TextSceneLoader::readBasicMaterialLink(const String& name){
00954 BasicMaterial* material =
00955 materialManager_->search(name)->castBasicMaterial();
00956 if(material == NULL){
00957 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
00958 "not found material %s (line %d)",
00959 name.getBytes(), tokenizer_->getLineNumber());
00960 }
00961 while(true){
00962 String token = readToken("readMaterialLink()");
00963 if(token == "}"){ break; }
00964 if(token == "baseTexture"){
00965
00966 String textureName = readToken("readBasicMaterialLink()");
00967 Texture* texture = textureManager_->search(textureName);
00968 if(texture == NULL){
00969 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
00970 "not found baseTexture %s (line %d)",
00971 textureName.getBytes(), tokenizer_->getLineNumber());
00972 }
00973 material->setBaseTexture(texture);
00974 }else if(token == "glossTexture"){
00975
00976 String textureName = readToken("readBasicMaterialLink()");
00977 Texture* texture = textureManager_->search(textureName);
00978 if(texture == NULL){
00979 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
00980 "not found glossTexture %s (line %d)",
00981 textureName.getBytes(), tokenizer_->getLineNumber());
00982 }
00983 material->setGlossTexture(texture);
00984 }else if(token == "lightTexture"){
00985
00986 String textureName = readToken("readBasicMaterialLink()");
00987 Texture* texture = textureManager_->search(textureName);
00988 if(texture == NULL){
00989 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
00990 "not found lightTexture %s (line %d)",
00991 textureName.getBytes(), tokenizer_->getLineNumber());
00992 }
00993 material->setLightTexture(texture);
00994 }else if(token == "stainTexture"){
00995
00996 String textureName = readToken("readBasicMaterialLink()");
00997 Texture* texture = textureManager_->search(textureName);
00998 if(texture == NULL){
00999 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
01000 "not found stainTexture %s (line %d)",
01001 textureName.getBytes(), tokenizer_->getLineNumber());
01002 }
01003 material->setStainTexture(texture);
01004 }else{
01005 ErrorOut("TextSceneLoader::readBasicMaterialLink() "
01006 "invalid token %s (line %d)",
01007 token.getBytes(), tokenizer_->getLineNumber());
01008 }
01009 }
01010 }
01011
01012
01013
01014
01015 void TextSceneLoader::readTextureLinkList(){
01016 openChunk();
01017 while(true){
01018 String token = readToken("readTextureLinkList()");
01019 if(token == "}"){ break; }
01020 readTextureLink(token);
01021 }
01022 }
01023
01024
01025 void TextSceneLoader::readTextureLink(const String& name){
01026 Texture* texture = textureManager_->search(name);
01027 if(texture == NULL){
01028 ErrorOut("TextSceneLoader::readTextureLink() "
01029 "not found texture %s (line %d)",
01030 name.getBytes(), tokenizer_->getLineNumber());
01031 }
01032 openChunk();
01033 while(true){
01034 String token = readToken("readTextureLink()");
01035 if(token == "}"){ break; }
01036
01037 Picture* picture = pictureManager_->search(token);
01038 if(picture == NULL){
01039 ErrorOut("TextSceneLoader::readTextureLink() "
01040 "not found picture %s (line %d)",
01041 token.getBytes(), tokenizer_->getLineNumber());
01042 }
01043 texture->addPicture(picture);
01044 }
01045 }
01046
01047
01048
01049
01050 bool TextSceneLoader::readBool(){
01051 String token = readToken("readBool()");
01052 if(token == "true"){ return true; }
01053 else if(token == "false"){ return false; }
01054 ErrorOut("TextSceneLoader::readBool() invalid token %s (line %d)",
01055 token.getBytes(), tokenizer_->getLineNumber());
01056 return false;
01057 }
01058
01059
01060 u_char TextSceneLoader::readUChar(){
01061 String token = readToken("readUChar()");
01062 u_char value = 0;
01063 bool result = token.parseUChar(&value);
01064 if(!result){
01065 ErrorOut("TextSceneLoader::readUChar() invalid token %s (line %d)",
01066 token.getBytes(), tokenizer_->getLineNumber());
01067 }
01068 return value;
01069 }
01070
01071
01072 u_short TextSceneLoader::readUShort(){
01073 String token = readToken("readUShort()");
01074 u_short value = 0;
01075 bool result = token.parseUShort(&value);
01076 if(!result){
01077 ErrorOut("TextSceneLoader::readUShort() invalid token %s (line %d)",
01078 token.getBytes(), tokenizer_->getLineNumber());
01079 }
01080 return value;
01081 }
01082
01083
01084 int TextSceneLoader::readInt(){
01085 String token = readToken("readInt()");
01086 int value = 0;
01087 bool result = token.parseInt(&value);
01088 if(!result){
01089 ErrorOut("TextSceneLoader::readInt() invalid token %s (line %d)",
01090 token.getBytes(), tokenizer_->getLineNumber());
01091 }
01092 return value;
01093 }
01094
01095
01096 u_int TextSceneLoader::readUInt(){
01097 String token = readToken("readInt()");
01098 u_int value = 0;
01099 bool result = token.parseUInt(&value);
01100 if(!result){
01101 ErrorOut("TextSceneLoader::readUInt() invalid token %s (line %d)",
01102 token.getBytes(), tokenizer_->getLineNumber());
01103 }
01104 return value;
01105 }
01106
01107
01108 float TextSceneLoader::readFloat(){
01109 String token = readToken("readFloat()");
01110 float value = 0.f;
01111 bool result = token.parseFloat(&value);
01112 if(!result){
01113 ErrorOut("TextSceneLoader::readFloat() invalid token %s (line %d)",
01114 token.getBytes(), tokenizer_->getLineNumber());
01115 }
01116 return value;
01117 }
01118
01119
01120 Vector3 TextSceneLoader::readVector3(){
01121 Vector3 result;
01122 openChunk();
01123 result.x = readFloat();
01124 result.y = readFloat();
01125 result.z = readFloat();
01126 closeChunk();
01127 return result;
01128 }
01129
01130
01131 Matrix34 TextSceneLoader::readMatrix34(){
01132 Matrix34 result;
01133 openChunk();
01134 for(int i = 0; i < 12; i++){
01135 result.array[i] = readFloat();
01136 }
01137 closeChunk();
01138 return result;
01139 }
01140
01141
01142 Color3c TextSceneLoader::readColor3c(){
01143 Color3c result;
01144 openChunk();
01145 result.r = readUChar();
01146 result.g = readUChar();
01147 result.b = readUChar();
01148 closeChunk();
01149 return result;
01150 }
01151
01152
01153 Color4c TextSceneLoader::readColor4c(){
01154 Color4c result;
01155 openChunk();
01156 result.r = readUChar();
01157 result.g = readUChar();
01158 result.b = readUChar();
01159 result.a = readUChar();
01160 closeChunk();
01161 return result;
01162 }
01163
01164
01165 Color3f TextSceneLoader::readColor3f(){
01166 Color3f result;
01167 openChunk();
01168 result.r = readFloat();
01169 result.g = readFloat();
01170 result.b = readFloat();
01171 closeChunk();
01172 return result;
01173 }
01174
01175
01176 Color4f TextSceneLoader::readColor4f(){
01177 Color4f result;
01178 openChunk();
01179 result.r = readFloat();
01180 result.g = readFloat();
01181 result.b = readFloat();
01182 result.a = readFloat();
01183 closeChunk();
01184 return result;
01185 }
01186
01187
01188 TexCoord2 TextSceneLoader::readTexCoord2(){
01189 TexCoord2 result;
01190 openChunk();
01191 result.u = readFloat();
01192 result.v = readFloat();
01193 closeChunk();
01194 return result;
01195 }
01196
01197
01198 AxisAlignedBox TextSceneLoader::readAxisAlignedBox(){
01199 AxisAlignedBox result;
01200 Vector3 minimum, maximum;
01201 openChunk();
01202 minimum.x = readFloat();
01203 minimum.y = readFloat();
01204 minimum.z = readFloat();
01205 closeChunk();
01206 openChunk();
01207 maximum.x = readFloat();
01208 maximum.y = readFloat();
01209 maximum.z = readFloat();
01210 closeChunk();
01211 result.set(minimum, maximum);
01212 return result;
01213 }
01214
01215
01216 Sphere TextSceneLoader::readSphere(){
01217 Sphere result;
01218 Vector3 vector;
01219 openChunk();
01220 vector.x = readFloat();
01221 vector.y = readFloat();
01222 vector.z = readFloat();
01223 result.setCenter(vector);
01224 result.setRadius(readFloat());
01225 closeChunk();
01226 return result;
01227 }
01228
01229
01230
01231
01232 String TextSceneLoader::readToken(const String& caller){
01233 bool hasNext = tokenizer_->nextToken();
01234 if(!hasNext){
01235 ErrorOut("TextSceneLoader::%s nothing token (line %d)",
01236 caller.getBytes(), tokenizer_->getLineNumber());
01237 }
01238 return tokenizer_->getToken();
01239 }
01240
01241
01242 void TextSceneLoader::skipWord(const String& word){
01243 String token = readToken("skipWord()");
01244 if(token != word){
01245 ErrorOut("TextSceneLoader::skipWord(%s) invalid token %s (line %d)",
01246 word.getBytes(), token.getBytes(), tokenizer_->getLineNumber());
01247 }
01248 }
01249
01250
01251 void TextSceneLoader::skipChunk(){
01252 int chunkLine = tokenizer_->getLineNumber();
01253 int chunkCounter = 0;
01254 while(true){
01255 bool hasNext = tokenizer_->nextToken();
01256 if(!hasNext){
01257 ErrorOut("TextSceneLoader::skipChunk(%d) nothing token (line %d)",
01258 chunkLine, tokenizer_->getLineNumber());
01259 }
01260 String token = tokenizer_->getToken();
01261 if(token == "{"){
01262 chunkCounter++;
01263 }else if(token == "}"){
01264 chunkCounter--;
01265
01266 if(chunkCounter == 0){ break; }
01267 if(chunkCounter < 0){
01268 ErrorOut("TextSceneLoader::skipChunk(%d) "
01269 "invalid chunk (line %d)",
01270 chunkLine, tokenizer_->getLineNumber());
01271 }
01272 }
01273 }
01274 }
01275
01276 }
01277