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

# BinarySceneLoader.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * バイナリシーンローダ実装
    00022  * @author Junpee
    00023  */
    00024
    00025 #include "LampBasic.h"
    00026 #include "Graphics/InputOutput/BinarySceneLoader.h"
    00027 #include "Core/InputOutput/BinaryFileReader.h"
    00028 #include "Core/InputOutput/FilePath.h"
    00029 #include "Core/Codec/Tga/TargaLoader.h"
    00030 #include "Graphics/Scene/Scene.h"
    00031 #include "Graphics/Fog/Fog.h"
    00032 #include "Graphics/SceneNode/SceneNodeManager.h"
    00033 #include "Graphics/Light/LightManager.h"
    00034 #include "Graphics/Model/ModelManager.h"
    00035 #include "Graphics/Mesh/MeshManager.h"
    00036 #include "Graphics/MeshData/MeshDataManager.h"
    00037 #include "Graphics/Material/MaterialManager.h"
    00038 #include "Graphics/Texture/TextureManager.h"
    00039 #include "Graphics/Picture/PictureManager.h"
    00040
    00041 namespace Lamp{
    00042
    00043 //------------------------------------------------------------------------------
    00044 // コンストラクタ
    00045 BinarySceneLoader::BinarySceneLoader(){
    00046 }
    00047 //------------------------------------------------------------------------------
    00048 // デストラクタ
    00049 BinarySceneLoader::~BinarySceneLoader(){
    00050 }
    00051 //------------------------------------------------------------------------------
    00052 // ロード
    00053 void BinarySceneLoader::load(const String& filePath, Scene* scene){
    00054     load(filePath, scene, scene->getRootNode());
    00055 }
    00056 //------------------------------------------------------------------------------
    00057 void BinarySceneLoader::load(const String& filePath, Scene* scene,
    00058     SceneNode* rootNode){
    00059     FilePath path(filePath);
    00060     Assert(path.existFile());
    00061     BinaryFileReader* binaryFileReader = new BinaryFileReader(filePath);
    00062     load(binaryFileReader, scene, rootNode, path.getFolderPath());
    00063     delete binaryFileReader;
    00064 }
    00065 //------------------------------------------------------------------------------
    00066 // ロード
    00067 void BinarySceneLoader::load(BinaryReader* binaryReader, Scene* scene,
    00068     const String& basePath){
    00069     load(binaryReader, scene, scene->getRootNode(), basePath);
    00070 }
    00071 //------------------------------------------------------------------------------
    00072 // ロード
    00073 void BinarySceneLoader::load(BinaryReader* binaryReader, Scene* scene,
    00074     SceneNode* rootNode, const String& basePath){
    00075     // 初期化
    00076     reader_ = binaryReader;
    00077     basePath_ = basePath;
    00078     scene_ = scene;
    00079     rootNode_ = rootNode;
    00080     sceneNodeManager_ = scene->getSceneNodeManager();
    00081     lightManager_ = scene->getLightManager();
    00082     modelManager_ = scene->getModelManager();
    00083     meshManager_ = scene->getMeshManager();
    00084     meshDataManager_ = scene->getMeshDataManager();
    00085     materialManager_ = scene->getMaterialManager();
    00086     textureManager_ = scene->getTextureManager();
    00087     pictureManager_ = scene->getPictureManager();
    00088
    00089     // ルートノードを無効にしておく
    00090     bool rootNodeEnabled = rootNode_->isEnabled();
    00091     rootNode_->setEnabled(false);
    00092
    00093     // ヘッダの読み込み
    00094     readHeader();
    00095
    00096     // 各ブロックの読み込み
    00097     while(true){
    00098         if(reader_->isEnd()){ break; }
    00099         String blockName = readID();
    00100         int blockSize = reader_->readInt();
    00101         // ブロック開始時にアライメントをとる
    00102         align();
    00103         int blockAddress = reader_->getPosition();
    00104         if(blockName == "Fog"){
    00105             readFog();
    00106         }else if(blockName == "SceneNode"){
    00107             readSceneNodeList(blockSize);
    00108         }else if(blockName == "Light"){
    00109             readLightList(blockSize);
    00110         }else if(blockName == "Model"){
    00111             readModelList(blockSize);
    00112         }else if(blockName == "Mesh"){
    00113             readMeshList(blockSize);
    00114         }else if(blockName == "MeshData"){
    00115             readMeshDataList(blockSize);
    00116         }else if(blockName == "Material"){
    00117             readMaterialList(blockSize);
    00118         }else if(blockName == "Texture"){
    00119             readTextureList(blockSize);
    00120         }else if(blockName == "Picture"){
    00121             readPictureList(blockSize);
    00122         }else if(blockName == "SceneNodeLin"){
    00123             readSceneNodeLinkList(blockSize);
    00124         }else if(blockName == "ModelLink"){
    00125             readModelLinkList(blockSize);
    00126         }else if(blockName == "MeshLink"){
    00127             readMeshLinkList(blockSize);
    00128         }else if(blockName == "MaterialLink"){
    00129             readMaterialLinkList(blockSize);
    00130         }else if(blockName == "TextureLink"){
    00131             readTextureLinkList(blockSize);
    00132         }else{
    00133 // ブロック開始アライメントが0なので大丈夫だけど、ちょっとまずい
    00134 // Writerではアライメント前のサイズがブロックサイズになってる
    00135             // 知らないブロックを読み飛ばす
    00136             DebugOut("BinarySceneLoader::load() "
    00137                 "Skip unknown block %s (%d)\n",
    00138                 blockName.getBytes(), reader_->getPosition());
    00139             reader_->skip(blockSize);
    00140         }
    00141         // 全てのブロックはアライメントをとる
    00142         align();
    00143         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00144     }
    00145
    00146     Assert(reader_->getPosition() == reader_->getSize());
    00147     rootNode_->setEnabled(rootNodeEnabled);
    00148 }
    00149 //------------------------------------------------------------------------------
    00150 // ヘッダの読み込み
    00151 void BinarySceneLoader::readHeader(){
    00152     // フォーマットIDの読み込み
    00153     if(readID() != "LBScene"){
    00154         ErrorOut("BinarySceneLoader::readHeader() "
    00155             "Invalid formatID (%d)", reader_->getPosition());
    00156     }
    00157     // バージョン番号の読み込み
    00158     u_int binaryVersion = 0x00000900;
    00159     u_int version = reader_->readUInt();
    00160     if(binaryVersion != version){
    00161         ErrorOut("BinarySceneLoader::readHeader() "
    00162             "Invalid version (%d)", reader_->getPosition());
    00163     }
    00164     align();
    00165 }
    00166 //------------------------------------------------------------------------------
    00167 // フォグ
    00168 //------------------------------------------------------------------------------
    00169 // フォグの読み込み
    00170 void BinarySceneLoader::readFog(){
    00171     Fog* fog = scene_->getFog();
    00172     // カラー
    00173     fog->setColor(readColor4c());
    00174     // モード
    00175     fog->setMode((Fog::Mode)reader_->readInt());
    00176     // 濃度
    00177     fog->setDensity(reader_->readFloat());
    00178     // ニア
    00179     fog->setNear(reader_->readFloat());
    00180     // ファー
    00181     fog->setFar(reader_->readFloat());
    00182     // 有効、無効
    00183     fog->setEnabled(reader_->readBool());
    00184 }
    00185 //------------------------------------------------------------------------------
    00186 // シーンノード
    00187 //------------------------------------------------------------------------------
    00188 // シーンノードリストの読み込み
    00189 void BinarySceneLoader::readSceneNodeList(int listSize){
    00190     int endAddress = reader_->getPosition() + listSize;
    00191     while(true){
    00192         if(endAddress == reader_->getPosition()){ break; }
    00193         Assert(!reader_->isEnd());
    00194         String blockName = readID();
    00195         int blockSize = reader_->readInt();
    00196         // ブロック開始時にアライメントをとる
    00197         align();
    00198         int blockAddress = reader_->getPosition();
    00199         if(blockName == "Standard"){
    00200             readSceneNode();
    00201         }else if(blockName == "LOD"){
    00202             readLODSceneNode();
    00203         }else{
    00204             // 知らないブロックを読み飛ばす
    00205             DebugOut("BinarySceneLoader::readSceneNodeList() "
    00206                 "Skip unknown sceneNode %s (%d)\n",
    00207                 blockName.getBytes(), reader_->getPosition());
    00208             reader_->skip(blockSize);
    00209         }
    00210         // 全てのブロックはアライメントをとる
    00211         align();
    00212         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00213     }
    00214 }
    00215 //------------------------------------------------------------------------------
    00216 // シーンノードの読み込み
    00217 void BinarySceneLoader::readSceneNode(){
    00218     SceneNode* sceneNode = sceneNodeManager_->createSceneNode(readString());
    00219     // スケール
    00220     sceneNode->setScale(readVector3());
    00221     // 回転
    00222     sceneNode->setRotationXYZ(readVector3());
    00223     // 移動
    00224     sceneNode->setTranslation(readVector3());
    00225     // 有効、無効フラグ
    00226     sceneNode->setEnabled(reader_->readBool());
    00227 }
    00228 //------------------------------------------------------------------------------
    00229 // レベルオブディティールシーンノードの読み込み
    00230 void BinarySceneLoader::readLODSceneNode(){
    00231     LODSceneNode* sceneNode =
    00232         sceneNodeManager_->createLODSceneNode(readString());
    00233     // スケール
    00234     sceneNode->setScale(readVector3());
    00235     // 回転
    00236     sceneNode->setRotationXYZ(readVector3());
    00237     // 移動
    00238     sceneNode->setTranslation(readVector3());
    00239     // LOD分割数
    00240     int lodThresholdCount = reader_->readInt();
    00241     sceneNode->setLODThresholdCount(lodThresholdCount);
    00242     // LOD分割値
    00243     for(int i = 0; i < lodThresholdCount; i++){
    00244         sceneNode->setLODThreshold(i, reader_->readFloat());
    00245     }
    00246     // 有効、無効フラグ
    00247     sceneNode->setEnabled(reader_->readBool());
    00248 }
    00249 //------------------------------------------------------------------------------
    00250 // ライト
    00251 //------------------------------------------------------------------------------
    00252 // ライトリストの読み込み
    00253 void BinarySceneLoader::readLightList(int listSize){
    00254     int endAddress = reader_->getPosition() + listSize;
    00255     while(true){
    00256         if(endAddress == reader_->getPosition()){ break; }
    00257         Assert(!reader_->isEnd());
    00258         String blockName = readID();
    00259         int blockSize = reader_->readInt();
    00260         // ブロック開始時にアライメントをとる
    00261         align();
    00262         int blockAddress = reader_->getPosition();
    00263         if(blockName == "Ambient"){
    00264             readAmbientLight();
    00265         }else if(blockName == "Directional"){
    00266             readDirectionalLight();
    00267         }else if(blockName == "Point"){
    00268             readPointLight();
    00269         }else{
    00270             // 知らないブロックを読み飛ばす
    00271             DebugOut("BinarySceneLoader::readLightList() "
    00272                 "Skip unknown light %s (%d)\n",
    00273                 blockName.getBytes(), reader_->getPosition());
    00274             reader_->skip(blockSize);
    00275         }
    00276         // 全てのブロックはアライメントをとる
    00277         align();
    00278         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00279     }
    00280 }
    00281 //------------------------------------------------------------------------------
    00282 // ライトの読み込み
    00283 void BinarySceneLoader::readLight(Light* light){
    00284     // ライトマスク
    00285     light->setLightMask(reader_->readUInt());
    00286     // 有効、無効フラグ
    00287     light->setEnabled(reader_->readBool());
    00288 }
    00289 //------------------------------------------------------------------------------
    00290 // アンビエントライトの読み込み
    00291 void BinarySceneLoader::readAmbientLight(){
    00292     AmbientLight* light = lightManager_->createAmbientLight(readString());
    00293     // ライトカラー
    00294     light->setColor(readColor3f());
    00295     // ライトの読み込み
    00296     readLight(light);
    00297 }
    00298 //------------------------------------------------------------------------------
    00299 // ディレクショナルライトの読み込み
    00300 void BinarySceneLoader::readDirectionalLight(){
    00301     DirectionalLight* light =
    00302         lightManager_->createDirectionalLight(readString());
    00303     // ディフューズカラー
    00304     light->setDiffuseColor(readColor3f());
    00305     // スペキュラカラー
    00306     light->setSpecularColor(readColor3f());
    00307     // 方向
    00308     light->setDirection(readVector3());
    00309     // ライトの読み込み
    00310     readLight(light);
    00311 }
    00312 //------------------------------------------------------------------------------
    00313 // ポイントライトの読み込み
    00314 void BinarySceneLoader::readPointLight(){
    00315     PointLight* light = lightManager_->createPointLight(readString());
    00316     // ディフューズカラー
    00317     light->setDiffuseColor(readColor3f());
    00318     // スペキュラカラー
    00319     light->setSpecularColor(readColor3f());
    00320     // 位置
    00321     light->setPosition(readVector3());
    00322     // レンジ
    00323     light->setRange(reader_->readFloat());
    00324     // 減衰係数
    00325     float attenuation0 = reader_->readFloat();
    00326     float attenuation1 = reader_->readFloat();
    00327     float attenuation2 = reader_->readFloat();
    00328     light->setAttenuation(attenuation0, attenuation1, attenuation2);
    00329     // ライトの読み込み
    00330     readLight(light);
    00331 }
    00332 //------------------------------------------------------------------------------
    00333 // モデル
    00334 //------------------------------------------------------------------------------
    00335 // モデルリストの読み込み
    00336 void BinarySceneLoader::readModelList(int listSize){
    00337     int endAddress = reader_->getPosition() + listSize;
    00338     while(true){
    00339         if(endAddress == reader_->getPosition()){ break; }
    00340         Assert(!reader_->isEnd());
    00341         String blockName = readID();
    00342         int blockSize = reader_->readInt();
    00343         // ブロック開始時にアライメントをとる
    00344         align();
    00345         int blockAddress = reader_->getPosition();
    00346         if(blockName == "Standard"){
    00347             readStandardModel();
    00348         }else if(blockName == "Character"){
    00349             readCharacterModel();
    00350         }else{
    00351             // 知らないブロックを読み飛ばす
    00352             DebugOut("BinarySceneLoader::readModelList() "
    00353                 "Skip unknown model %s (%d)\n",
    00354                 blockName.getBytes(), reader_->getPosition());
    00355             reader_->skip(blockSize);
    00356         }
    00357         // 全てのブロックはアライメントをとる
    00358         align();
    00359         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00360     }
    00361 }
    00362 //------------------------------------------------------------------------------
    00363 // 標準モデルの読み込み
    00364 void BinarySceneLoader::readStandardModel(){
    00365     StandardModel* model = modelManager_->createStandardModel(readString());
    00366     // 有効、無効フラグ
    00367     model->setEnabled(reader_->readBool());
    00368 }
    00369 //------------------------------------------------------------------------------
    00370 // キャラクタモデルの読み込み
    00371 void BinarySceneLoader::readCharacterModel(){
    00372     CharacterModel* model = modelManager_->createCharacterModel(readString());
    00373     // 有効、無効フラグ
    00374     model->setEnabled(reader_->readBool());
    00375     // アライメント
    00376     align();
    00377     // ボーン数
    00378     int boneCount = reader_->readInt();
    00379     // ボーンの読み込み
    00380     for(int i = 0; i < boneCount; i++){ readBone(model); }
    00381     // ボーンリンク
    00382     for(int i = 0; i < boneCount; i++){
    00383         Bone* parent = model->getBone(i);
    00384         int childCount = reader_->readInt();
    00385         for(int j = 0; j < childCount; j++){
    00386             parent->addBone(model->getBone(reader_->readInt()));
    00387         }
    00388     }
    00389 }
    00390 //------------------------------------------------------------------------------
    00391 // ボーンの読み込み
    00392 void BinarySceneLoader::readBone(CharacterModel* model){
    00393     Bone* bone = model->createBone(readString());
    00394     // ポーズ逆行列
    00395     bone->setInversePoseMatrix(readMatrix34());
    00396     // スケール
    00397     bone->setScale(readVector3());
    00398     // 回転
    00399     bone->setRotationXYZ(readVector3());
    00400     // 移動
    00401     bone->setTranslation(readVector3());
    00402 }
    00403 //------------------------------------------------------------------------------
    00404 // メッシュ
    00405 //------------------------------------------------------------------------------
    00406 // メッシュリストの読み込み
    00407 void BinarySceneLoader::readMeshList(int listSize){
    00408     int endAddress = reader_->getPosition() + listSize;
    00409     while(true){
    00410         if(endAddress == reader_->getPosition()){ break; }
    00411         Assert(!reader_->isEnd());
    00412         String blockName = readID();
    00413         int blockSize = reader_->readInt();
    00414         // ブロック開始時にアライメントをとる
    00415         align();
    00416         int blockAddress = reader_->getPosition();
    00417         if(blockName == "Rigid"){
    00418             readRigidMesh();
    00419         }else if(blockName == "Character"){
    00420             readCharacterMesh();
    00421         }else{
    00422             // 知らないブロックを読み飛ばす
    00423             DebugOut("BinarySceneLoader::readMeshList() "
    00424                 "Skip unknown mesh %s (%d)\n",
    00425                 blockName.getBytes(), reader_->getPosition());
    00426             reader_->skip(blockSize);
    00427         }
    00428         // 全てのブロックはアライメントをとる
    00429         align();
    00430         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00431     }
    00432 }
    00433 //------------------------------------------------------------------------------
    00434 // 剛体メッシュの読み込み
    00435 void BinarySceneLoader::readRigidMesh(){
    00436     RigidMesh* mesh = meshManager_->createRigidMesh(readString());
    00437     // 有効、無効フラグ
    00438     mesh->setEnabled(reader_->readBool());
    00439 }
    00440 //------------------------------------------------------------------------------
    00441 // キャラクタメッシュの読み込み
    00442 void BinarySceneLoader::readCharacterMesh(){
    00443     CharacterMesh* mesh = meshManager_->createCharacterMesh(readString());
    00444     // 有効、無効フラグ
    00445     mesh->setEnabled(reader_->readBool());
    00446 }
    00447 //------------------------------------------------------------------------------
    00448 // メッシュデータ
    00449 //------------------------------------------------------------------------------
    00450 // メッシュデータリストの読み込み
    00451 void BinarySceneLoader::readMeshDataList(int listSize){
    00452     int endAddress = reader_->getPosition() + listSize;
    00453     while(true){
    00454         if(endAddress == reader_->getPosition()){ break; }
    00455         Assert(!reader_->isEnd());
    00456         readMeshData();
    00457     }
    00458 }
    00459 //------------------------------------------------------------------------------
    00460 // メッシュデータの読み込み
    00461 void BinarySceneLoader::readMeshData(){
    00462     MeshData* meshData = meshDataManager_->createMeshData(readString());
    00463     // バウンディングボックス
    00464     meshData->setBoundingBox(readAxisAlignedBox());
    00465     // バウンディングスフィア
    00466     meshData->setBoundingSphere(readSphere());
    00467     // プリミティブタイプ
    00468     meshData->setPrimitiveType((Mesh::PrimitiveType)reader_->readInt());
    00469     // 頂点インデックス数
    00470     int vertexIndexCount = reader_->readInt();
    00471     if(vertexIndexCount > 0){
    00472         meshData->setVertexIndexCount(vertexIndexCount);
    00473         for(int i = 0; i < vertexIndexCount; i++){
    00474             meshData->setVertexIndex(i, reader_->readUShort());
    00475         }
    00476     }
    00477     // 法線を持っているか
    00478     bool hasNormal = reader_->readBool();
    00479     meshData->enableNormal(hasNormal);
    00480     // 頂点カラーを持っているか
    00481     bool hasColor = reader_->readBool();
    00482     meshData->enableColor(hasColor);
    00483     // アライメント
    00484     align();
    00485     // 頂点数
    00486     int vertexCount = reader_->readInt();
    00487     meshData->setVertexCount(vertexCount);
    00488     // テクスチャ座標セット数
    00489     int texCoordSetCount = reader_->readInt();
    00490     meshData->setTexCoordSetCount(texCoordSetCount);
    00491     // テクスチャ座標タイプ
    00492     int texCoordType[TexCoord::maxSetCount];
    00493     for(int i = 0; i < texCoordSetCount; i++){
    00494         texCoordType[i] = reader_->readInt();
    00495         meshData->setTexCoordType(i, (TexCoord::Type)texCoordType[i]);
    00496     }
    00497     // 位置
    00498     for(int i = 0; i < vertexCount; i++){
    00499         meshData->setPosition(i, readVector3());
    00500     }
    00501     // 法線
    00502     if(hasNormal){
    00503         for(int i = 0; i < vertexCount; i++){
    00504             meshData->setNormal(i, readVector3());
    00505         }
    00506     }
    00507     // 頂点カラー
    00508     if(hasColor){
    00509         for(int i = 0; i < vertexCount; i++){
    00510             meshData->setColor(i, readColor4c());
    00511         }
    00512     }
    00513     // テクスチャ座標
    00514     float texCoord[4];
    00515     for(int i = 0; i < texCoordSetCount; i++){
    00516         int texCoordSize = sizeof(float) * texCoordType[i];
    00517         for(int j = 0; j < vertexCount; j++){
    00518             reader_->readBytes(texCoord, texCoordSize);
    00519             meshData->setTexCoord(j, i, texCoord, texCoordType[i]);
    00520         }
    00521     }
    00522     // 頂点当たりボーン数
    00523     int bonesPerVertex = reader_->readInt();
    00524     meshData->setBonesPerVertex(bonesPerVertex);
    00525     if(bonesPerVertex > 0){
    00526         for(int i = 0; i < vertexCount; i++){
    00527             for(int j = 0; j < bonesPerVertex; j++){
    00528                 meshData->setBoneIndex(i, j, reader_->readUChar());
    00529             }
    00530         }
    00531     }
    00532     // 頂点あたりウェイト数
    00533     int weightsPerVertex = meshData->getWeightsPerVertex();
    00534     if(weightsPerVertex > 0){
    00535         for(int i = 0; i < vertexCount; i++){
    00536             for(int j = 0; j < weightsPerVertex; j++){
    00537                 meshData->setWeight(i, j, reader_->readFloat());
    00538             }
    00539         }
    00540     }
    00541     // アライメント
    00542     align();
    00543 }
    00544 //------------------------------------------------------------------------------
    00545 // マテリアル
    00546 //------------------------------------------------------------------------------
    00547 // マテリアルリストの読み込み
    00548 void BinarySceneLoader::readMaterialList(int listSize){
    00549     int endAddress = reader_->getPosition() + listSize;
    00550     while(true){
    00551         if(endAddress == reader_->getPosition()){ break; }
    00552         Assert(!reader_->isEnd());
    00553         String blockName = readID();
    00554         int blockSize = reader_->readInt();
    00555         // ブロック開始時にアライメントをとる
    00556         align();
    00557         int blockAddress = reader_->getPosition();
    00558         if(blockName == "Basic"){
    00559             readBasicMaterial();
    00560         }else{
    00561             // 知らないブロックを読み飛ばす
    00562             DebugOut("BinarySceneLoader::readMaterialList() "
    00563                 "Skip unknown material %s (%d)\n",
    00564                 blockName.getBytes(), reader_->getPosition());
    00565             reader_->skip(blockSize);
    00566         }
    00567         // 全てのブロックはアライメントをとる
    00568         align();
    00569         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00570     }
    00571 }
    00572 //------------------------------------------------------------------------------
    00573 // マテリアルの読み込み
    00574 void BinarySceneLoader::readMaterial(Material* material){
    00575     // 優先度
    00576     material->setPriority(reader_->readInt());
    00577     // ブレンドモード
    00578     material->setBlendMode((Material::BlendMode)reader_->readInt());
    00579     // アルファ値
    00580     material->setAlpha(reader_->readFloat());
    00581     // ブレンドソース
    00582     material->setBlendSource((Material::BlendState)reader_->readInt());
    00583     // ブレンドデスティネーション
    00584     material->setBlendDestination((Material::BlendState)reader_->readInt());
    00585     // フォグオプション
    00586     material->setFogOption((Material::FogOption)reader_->readInt());
    00587     // ライトマスク
    00588     material->setLightMask(reader_->readUInt());
    00589     // Z書き込み
    00590     material->setZWrite(reader_->readBool());
    00591     // Zテスト
    00592     material->setZTest(reader_->readBool());
    00593     // アライメント
    00594     align();
    00595 }
    00596 //------------------------------------------------------------------------------
    00597 // 基本マテリアルの読み込み
    00598 void BinarySceneLoader::readBasicMaterial(){
    00599     BasicMaterial* material =
    00600         materialManager_->createBasicMaterial(readString());
    00601     // マテリアル読み込み
    00602     readMaterial(material);
    00603     // ベースUVインデックス
    00604     material->setBaseUVIndex(reader_->readInt());
    00605     // 光沢UVインデックス
    00606     material->setGlossUVIndex(reader_->readInt());
    00607     // ライトUVインデックス
    00608     material->setLightUVIndex(reader_->readInt());
    00609     // 汚れUVインデックス
    00610     material->setStainUVIndex(reader_->readInt());
    00611     // ディフューズカラー
    00612     material->setDiffuseColor(readColor3f());
    00613     // スペキュラカラー
    00614     material->setSpecularColor(readColor3f());
    00615     // スペキュラパワー
    00616     material->setSpecularPower(reader_->readFloat());
    00617     // アンビエントカラー
    00618     material->setAmbientColor(readColor3f());
    00619     // エミッシブカラー
    00620     material->setEmissiveColor(readColor3f());
    00621 }
    00622 //------------------------------------------------------------------------------
    00623 // テクスチャ
    00624 //------------------------------------------------------------------------------
    00625 // テクスチャリストの読み込み
    00626 void BinarySceneLoader::readTextureList(int listSize){
    00627     int endAddress = reader_->getPosition() + listSize;
    00628     while(true){
    00629         if(endAddress == reader_->getPosition()){ break; }
    00630         Assert(!reader_->isEnd());
    00631         String blockName = readID();
    00632         int blockSize = reader_->readInt();
    00633         // ブロック開始時にアライメントをとる
    00634         align();
    00635         int blockAddress = reader_->getPosition();
    00636         if(blockName == "Surface"){
    00637             readSurfaceTexture();
    00638         }else{
    00639             // 知らないブロックを読み飛ばす
    00640             DebugOut("BinarySceneLoader::readTextureList() "
    00641                 "Skip unknown texture %s (%d)\n",
    00642                 blockName.getBytes(), reader_->getPosition());
    00643             reader_->skip(blockSize);
    00644         }
    00645         // 全てのブロックはアライメントをとる
    00646         align();
    00647         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00648     }
    00649 }
    00650 //------------------------------------------------------------------------------
    00651 // サーフェーステクスチャの読み込み
    00652 void BinarySceneLoader::readSurfaceTexture(){
    00653     SurfaceTexture* texture =
    00654         textureManager_->createSurfaceTexture(readString());
    00655     // アドレスモードU
    00656     texture->setAddressModeU((Texture::AddressMode)reader_->readInt());
    00657     // アドレスモードV
    00658     texture->setAddressModeV((Texture::AddressMode)reader_->readInt());
    00659     // リピートUV
    00660     texture->setRepeatUV(readTexCoord2());
    00661     // オフセットUV
    00662     texture->setOffsetUV(readTexCoord2());
    00663 }
    00664 //------------------------------------------------------------------------------
    00665 // ピクチャ
    00666 //------------------------------------------------------------------------------
    00667 // ピクチャリストの読み込み
    00668 void BinarySceneLoader::readPictureList(int listSize){
    00669     int endAddress = reader_->getPosition() + listSize;
    00670     while(true){
    00671         if(endAddress == reader_->getPosition()){ break; }
    00672         Assert(!reader_->isEnd());
    00673         String name = readString();
    00674         String path = readString();
    00675         // 拡張子を取得
    00676         FilePath filePath(path);
    00677         String extension = filePath.getExtension();
    00678         // 拡張子にあわせてピクチャを読み分ける
    00679         Picture* picture;
    00680         if(extension == "tga"){
    00681             TargaLoader loader(basePath_ + path);
    00682             loader.loadHeader();
    00683             // アルファの有無
    00684             if(loader.hasAlpha()){
    00685                 picture = readPictureRGBA8(name, loader);
    00686             }else{
    00687                 picture = readPictureRGB8(name, loader);
    00688             }
    00689         }else{
    00690             ErrorOut("BinarySceneLoader::readPictureList() "
    00691                 "Unsupported picture format %s (%d)",
    00692                 path.getBytes(), reader_->getPosition());
    00693             return;
    00694         }
    00695         // パスを設定する
    00696         picture->setPath(path);
    00697     }
    00698 }
    00699 //------------------------------------------------------------------------------
    00700 // RGB8ビットピクチャの読み込み
    00701 Picture* BinarySceneLoader::readPictureRGB8(
    00702     const String& name, TargaLoader& loader){
    00703     PictureRGB8* picture = pictureManager_->createPictureRGB8(name);
    00704     picture->setSize(loader.getSize());
    00705     loader.loadImage(picture->getImageBuffer());
    00706     return picture;
    00707 }
    00708 //------------------------------------------------------------------------------
    00709 // RGBA8ビットピクチャの読み込み
    00710 Picture* BinarySceneLoader::readPictureRGBA8(
    00711     const String& name, TargaLoader& loader){
    00712     PictureRGBA8* picture = pictureManager_->createPictureRGBA8(name);
    00713     picture->setSize(loader.getSize());
    00714     loader.loadImage(picture->getImageBuffer());
    00715     return picture;
    00716 }
    00717 //------------------------------------------------------------------------------
    00718 // シーンノードリンク
    00719 //------------------------------------------------------------------------------
    00720 // シーンノードリンクリストの読み込み
    00721 void BinarySceneLoader::readSceneNodeLinkList(int listSize){
    00722     int endAddress = reader_->getPosition() + listSize;
    00723     while(true){
    00724         if(endAddress == reader_->getPosition()){ break; }
    00725         Assert(!reader_->isEnd());
    00726         readSceneNodeLink();
    00727     }
    00728 }
    00729 //------------------------------------------------------------------------------
    00730 // シーンノードリンクの読み込み
    00731 void BinarySceneLoader::readSceneNodeLink(){
    00732     String name = readString();
    00733     SceneNode* sceneNode;
    00734     if(name.equals("RootNode")){
    00735         sceneNode = rootNode_;
    00736     }else{
    00737         sceneNode = sceneNodeManager_->search(name);
    00738         if(sceneNode == NULL){
    00739             ErrorOut("BinarySceneLoader::readSceneNodeLink() "
    00740                 "not found source sceneNode %s (%d)",
    00741                 name.getBytes(), reader_->getPosition());
    00742         }
    00743     }
    00744     // シーンノードリンク
    00745     int sceneNodeCount = reader_->readInt();
    00746     for(int i = 0; i < sceneNodeCount; i++){
    00747         String targetName = readString();
    00748         SceneNode* target = sceneNodeManager_->search(targetName);
    00749         if(target == NULL){
    00750             ErrorOut("BinarySceneLoader::readSceneNodeLink() "
    00751                 "not found target sceneNode %s (%d)",
    00752                 targetName.getBytes(), reader_->getPosition());
    00753         }
    00754         sceneNode->addSceneNode(target);
    00755     }
    00756     // シーンリーフリンク
    00757     int sceneLeafCount = reader_->readInt();
    00758     for(int i = 0; i < sceneLeafCount; i++){
    00759         int type = reader_->readInt();
    00760         String targetName = readString();
    00761         SceneLeaf* sceneLeaf = NULL;
    00762         if(type == 0){
    00763             sceneLeaf = modelManager_->search(targetName);
    00764         }else if(type == 1){
    00765             sceneLeaf = lightManager_->search(targetName);
    00766         }else{
    00767             ErrorOut("BinarySceneLoader::readSceneNodeLink() "
    00768                 "unsupported SceneLeafType %s %d (%d)",
    00769                 targetName.getBytes(), type, reader_->getPosition());
    00770         }
    00771         if(sceneLeaf == NULL){
    00772             ErrorOut("BinarySceneLoader::readSceneNodeLink() "
    00773                 "not found target SceneLeaf %s (%d)",
    00774                 targetName.getBytes(), reader_->getPosition());
    00775         }
    00776         sceneNode->addSceneLeaf(sceneLeaf);
    00777     }
    00778 }
    00779 //------------------------------------------------------------------------------
    00780 // モデルリンク
    00781 //------------------------------------------------------------------------------
    00782 // モデルリンクリストの読み込み
    00783 void BinarySceneLoader::readModelLinkList(int listSize){
    00784     int endAddress = reader_->getPosition() + listSize;
    00785     while(true){
    00786         if(endAddress == reader_->getPosition()){ break; }
    00787         Assert(!reader_->isEnd());
    00788         readModelLink();
    00789     }
    00790 }
    00791 //------------------------------------------------------------------------------
    00792 // モデルリンクの読み込み
    00793 void BinarySceneLoader::readModelLink(){
    00794     String name = readString();
    00795     Model* model = modelManager_->search(name);
    00796     if(model == NULL){
    00797         ErrorOut("BinarySceneLoader::readModelLink() "
    00798             "not found source model %s (%d)",
    00799             name.getBytes(), reader_->getPosition());
    00800     }
    00801     // メッシュリンク
    00802     int meshCount = reader_->readInt();
    00803     for(int i = 0; i < meshCount; i++){
    00804         String targetName = readString();
    00805         Mesh* target = meshManager_->search(targetName);
    00806         if(target == NULL){
    00807             ErrorOut("BinarySceneLoader::readModelLink() "
    00808                 "not found target mesh %s (%d)",
    00809                 targetName.getBytes(), reader_->getPosition());
    00810         }
    00811         model->addMesh(target);
    00812     }
    00813 }
    00814 //------------------------------------------------------------------------------
    00815 // メッシュリンク
    00816 //------------------------------------------------------------------------------
    00817 // メッシュリンクリストの読み込み
    00818 void BinarySceneLoader::readMeshLinkList(int listSize){
    00819     int endAddress = reader_->getPosition() + listSize;
    00820     while(true){
    00821         if(endAddress == reader_->getPosition()){ break; }
    00822         Assert(!reader_->isEnd());
    00823         readMeshLink();
    00824     }
    00825 }
    00826 //------------------------------------------------------------------------------
    00827 // メッシュリンクの読み込み
    00828 void BinarySceneLoader::readMeshLink(){
    00829     String name = readString();
    00830     Mesh* mesh = meshManager_->search(name);
    00831     if(mesh == NULL){
    00832         ErrorOut("BinarySceneLoader::readMeshLink() "
    00833             "not found source mesh %s (%d)",
    00834             name.getBytes(), reader_->getPosition());
    00835     }
    00836     // メッシュデータを持つか
    00837     bool hasMeshData = reader_->readBool();
    00838     // マテリアルを持つか
    00839     bool hasMaterial = reader_->readBool();
    00840     Assert(hasMeshData || hasMaterial);
    00841     // アライメント
    00842     align();
    00843     // メッシュデータリンク
    00844     if(hasMeshData){
    00845         String targetName = readString();
    00846         MeshData* target = meshDataManager_->search(targetName);
    00847         if(target == NULL){
    00848             ErrorOut("BinarySceneLoader::readMeshLink() "
    00849                 "not found target meshData %s (%d)",
    00850                 targetName.getBytes(), reader_->getPosition());
    00851         }
    00852         mesh->setMeshData(target);
    00853     }
    00854     // マテリアルリンク
    00855     if(hasMaterial){
    00856         String targetName = readString();
    00857         Material* target = materialManager_->search(targetName);
    00858         if(target == NULL){
    00859             ErrorOut("BinarySceneLoader::readMeshLink() "
    00860                 "not found target material %s (%d)",
    00861                 targetName.getBytes(), reader_->getPosition());
    00862         }
    00863         mesh->setMaterial(target);
    00864     }
    00865 }
    00866 //------------------------------------------------------------------------------
    00867 // マテリアルリンク
    00868 //------------------------------------------------------------------------------
    00869 // マテリアルリンクリストの読み込み
    00870 void BinarySceneLoader::readMaterialLinkList(int listSize){
    00871     int endAddress = reader_->getPosition() + listSize;
    00872     while(true){
    00873         if(endAddress == reader_->getPosition()){ break; }
    00874         Assert(!reader_->isEnd());
    00875         String blockName = readID();
    00876         int blockSize = reader_->readInt();
    00877         // ブロック開始時にアライメントをとる
    00878         align();
    00879         int blockAddress = reader_->getPosition();
    00880         if(blockName == "Basic"){
    00881             readBasicMaterialLink();
    00882         }else{
    00883             // 知らないブロックを読み飛ばす
    00884             DebugOut("BinarySceneLoader::readMaterialList() "
    00885                 "Skip unknown material %s (%d)\n",
    00886                 blockName.getBytes(), reader_->getPosition());
    00887             reader_->skip(blockSize);
    00888         }
    00889         // 全てのブロックはアライメントをとる
    00890         align();
    00891         Assert((reader_->getPosition() - blockAddress) == blockSize);
    00892     }
    00893
    00894 }
    00895 //------------------------------------------------------------------------------
    00896 // 基本マテリアルリンクの読み込み
    00897 void BinarySceneLoader::readBasicMaterialLink(){
    00898     String name = readString();
    00899     Material* material = materialManager_->search(name);
    00900     if(material == NULL){
    00901         ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00902             "Not found material %s (%d)",
    00903             name.getBytes(), reader_->getPosition());
    00904     }
    00905     BasicMaterial* basicMaterial = material->castBasicMaterial();
    00906     if(basicMaterial == NULL){
    00907         ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00908             "Invalid type material %s (%d)",
    00909             name.getBytes(), reader_->getPosition());
    00910     }
    00911     bool hasBaseTexture = reader_->readBool();
    00912     bool hasGlossTexture = reader_->readBool();
    00913     bool hasLightTexture = reader_->readBool();
    00914     bool hasStainTexture = reader_->readBool();
    00915     align();
    00916     if(hasBaseTexture){
    00917         String textureName = readString();
    00918         Texture* texture = textureManager_->search(textureName);
    00919         if(texture == NULL){
    00920             ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00921                 "Not found texture %s (%d)",
    00922                 textureName.getBytes(), reader_->getPosition());
    00923         }
    00924         basicMaterial->setBaseTexture(texture);
    00925     }
    00926     if(hasGlossTexture){
    00927         String textureName = readString();
    00928         Texture* texture = textureManager_->search(textureName);
    00929         if(texture == NULL){
    00930             ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00931                 "Not found texture %s (%d)",
    00932                 textureName.getBytes(), reader_->getPosition());
    00933         }
    00934         basicMaterial->setGlossTexture(texture);
    00935     }
    00936     if(hasLightTexture){
    00937         String textureName = readString();
    00938         Texture* texture = textureManager_->search(textureName);
    00939         if(texture == NULL){
    00940             ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00941                 "Not found texture %s (%d)",
    00942                 textureName.getBytes(), reader_->getPosition());
    00943         }
    00944         basicMaterial->setLightTexture(texture);
    00945     }
    00946     if(hasStainTexture){
    00947         String textureName = readString();
    00948         Texture* texture = textureManager_->search(textureName);
    00949         if(texture == NULL){
    00950             ErrorOut("BinarySceneLoader::readBasicMaterialLink() "
    00951                 "Not found texture %s (%d)",
    00952                 textureName.getBytes(), reader_->getPosition());
    00953         }
    00954         basicMaterial->setStainTexture(texture);
    00955     }
    00956 }
    00957 //------------------------------------------------------------------------------
    00958 // テクスチャリンク
    00959 //------------------------------------------------------------------------------
    00960 // テクスチャリンクリストの読み込み
    00961 void BinarySceneLoader::readTextureLinkList(int listSize){
    00962     int endAddress = reader_->getPosition() + listSize;
    00963     while(true){
    00964         if(endAddress == reader_->getPosition()){ break; }
    00965         Assert(!reader_->isEnd());
    00966         readTextureLink();
    00967     }
    00968 }
    00969 //------------------------------------------------------------------------------
    00970 // テクスチャリンクの読み込み
    00971 void BinarySceneLoader::readTextureLink(){
    00972     String name = readString();
    00973     Texture* texture = textureManager_->search(name);
    00974     if(texture == NULL){
    00975         ErrorOut("BinarySceneLoader::readTextureLink() "
    00976             "not found source texture %s (%d)",
    00977             name.getBytes(), reader_->getPosition());
    00978     }
    00979     // ピクチャリンク
    00980     int pictureCount = reader_->readInt();
    00981     for(int i = 0; i < pictureCount; i++){
    00982         String targetName = readString();
    00983         Picture* target = pictureManager_->search(targetName);
    00984         if(target == NULL){
    00985             ErrorOut("BinarySceneLoader::readTextureLink() "
    00986                 "not found target picture %s (%d)",
    00987                 targetName.getBytes(), reader_->getPosition());
    00988         }
    00989         texture->addPicture(target);
    00990     }
    00991 }
    00992 //------------------------------------------------------------------------------
    00993 // 値の読み込み
    00994 //------------------------------------------------------------------------------
    00995 // 文字列の読み込み
    00996 String BinarySceneLoader::readString(){
    00997     String result;
    00998     int size = reader_->readInt();
    00999     if(size > stringBufferSize_){
    01000         char* allocateBuffer = new char[size];
    01001         reader_->readBytes(allocateBuffer, size);
    01002         result = allocateBuffer;
    01003         delete allocateBuffer;
    01004     }else{
    01005         reader_->readBytes(stringBuffer_, size);
    01006         result = stringBuffer_;
    01007     }
    01008     align();
    01009     return result;
    01010 }
    01011 //------------------------------------------------------------------------------
    01012 // 三次元ベクトルの読み込み
    01013 Vector3 BinarySceneLoader::readVector3(){
    01014     Vector3 result;
    01015     reader_->readBytes(result.array, sizeof(Vector3));
    01016     return result;
    01017 }
    01018 //------------------------------------------------------------------------------
    01019 // Matrix34値の読み込み
    01020 Matrix34 BinarySceneLoader::readMatrix34(){
    01021     Matrix34 result;
    01022     reader_->readBytes(result.array, sizeof(Matrix34));
    01023     return result;
    01024 }
    01025 //------------------------------------------------------------------------------
    01026 // 三要素整数カラー値の読み込み
    01027 Color3c BinarySceneLoader::readColor3c(){
    01028     Color3c result;
    01029     reader_->readBytes(result.array, sizeof(Color3c));
    01030     return result;
    01031 }
    01032 //------------------------------------------------------------------------------
    01033 // 四要素整数カラー値の読み込み
    01034 Color4c BinarySceneLoader::readColor4c(){
    01035     Color4c result;
    01036     reader_->readBytes(result.array, sizeof(Color4c));
    01037     return result;
    01038 }
    01039 //------------------------------------------------------------------------------
    01040 // 三要素実数カラー値の読み込み
    01041 Color3f BinarySceneLoader::readColor3f(){
    01042     Color3f result;
    01043     reader_->readBytes(result.array, sizeof(Color3f));
    01044     return result;
    01045 }
    01046 //------------------------------------------------------------------------------
    01047 // 四要素実数カラー値の読み込み
    01048 Color4f BinarySceneLoader::readColor4f(){
    01049     Color4f result;
    01050     reader_->readBytes(result.array, sizeof(Color4f));
    01051     return result;
    01052 }
    01053 //------------------------------------------------------------------------------
    01054 // 二次元テクスチャ座標値の読み込み
    01055 TexCoord2 BinarySceneLoader::readTexCoord2(){
    01056     TexCoord2 result;
    01057     reader_->readBytes(result.array, sizeof(TexCoord2));
    01058     return result;
    01059 }
    01060 //------------------------------------------------------------------------------
    01061 // 軸沿いボックスの読み込み
    01062 AxisAlignedBox BinarySceneLoader::readAxisAlignedBox(){
    01063     AxisAlignedBox result;
    01064     reader_->readBytes(&result, sizeof(AxisAlignedBox));
    01065     return result;
    01066 }
    01067 //------------------------------------------------------------------------------
    01068 // 球の読み込み
    01069 Sphere BinarySceneLoader::readSphere(){
    01070     Sphere result;
    01071     reader_->readBytes(&result, sizeof(Sphere));
    01072     return result;
    01073 }
    01074 //------------------------------------------------------------------------------
    01075 // ユーティリティ
    01076 //------------------------------------------------------------------------------
    01077 // アライメントを取る
    01078 void BinarySceneLoader::align(){
    01079     reader_->align(16);
    01080 }
    01081 //------------------------------------------------------------------------------
    01082 // IDの読み込み
    01083 String BinarySceneLoader::readID(){
    01084     char buffer[13];
    01085     buffer[12] = 0;
    01086     reader_->readBytes(buffer, 12);
    01087     return String(buffer);
    01088 }
    01089 //------------------------------------------------------------------------------
    01090 } // End of namespace Lamp
    01091 //------------------------------------------------------------------------------