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

# BinarySceneSaver.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 <direct.h>
    00027 #include "Graphics/InputOutput/BinarySceneSaver.h"
    00028 #include "Core/InputOutput/BinaryFileWriter.h"
    00029 #include "Core/InputOutput/FilePath.h"
    00030 #include "Core/Codec/Tga/TargaSaver.h"
    00031 #include "Graphics/Scene/Scene.h"
    00032 #include "Graphics/Fog/Fog.h"
    00033 #include "Graphics/Light/LightManager.h"
    00034 #include "Graphics/SceneNode/SceneNodeManager.h"
    00035 #include "Graphics/Model/ModelManager.h"
    00036 #include "Graphics/Mesh/MeshManager.h"
    00037 #include "Graphics/MeshData/MeshDataManager.h"
    00038 #include "Graphics/Material/MaterialManager.h"
    00039 #include "Graphics/Texture/TextureManager.h"
    00040 #include "Graphics/Picture/PictureManager.h"
    00041
    00042 namespace Lamp{
    00043
    00044 //------------------------------------------------------------------------------
    00045 // コンストラクタ
    00046 BinarySceneSaver::BinarySceneSaver(){
    00047 }
    00048 //------------------------------------------------------------------------------
    00049 // デストラクタ
    00050 BinarySceneSaver::~BinarySceneSaver(){
    00051 }
    00052 //------------------------------------------------------------------------------
    00053 // セーブ
    00054 void BinarySceneSaver::save(const String& filePath, Scene* scene){
    00055     FilePath path(filePath);
    00056     BinaryFileWriter* binaryFileWriter = new BinaryFileWriter(filePath);
    00057     save(binaryFileWriter, scene, path.getFolderPath());
    00058     delete binaryFileWriter;
    00059 }
    00060 //------------------------------------------------------------------------------
    00061 // セーブ
    00062 void BinarySceneSaver::save(BinaryWriter* binaryWriter, Scene* scene,
    00063     const String& basePath){
    00064     // 初期化
    00065     writer_ = binaryWriter;
    00066     basePath_ = basePath;
    00067     scene_ = scene;
    00068     sceneNodeManager_ = scene->getSceneNodeManager();
    00069     lightManager_ = scene->getLightManager();
    00070     modelManager_ = scene->getModelManager();
    00071     meshManager_ = scene->getMeshManager();
    00072     meshDataManager_ = scene->getMeshDataManager();
    00073     materialManager_ = scene->getMaterialManager();
    00074     textureManager_ = scene->getTextureManager();
    00075     pictureManager_ = scene->getPictureManager();
    00076
    00077     // ヘッダの書き出し
    00078     writeHeader();
    00079
    00080     // オブジェクトリストの書き出し
    00081     int linkCount = writeObjectList();
    00082
    00083     // リンクの書き出し
    00084     writeLink(linkCount);
    00085 }
    00086 //------------------------------------------------------------------------------
    00087 // ヘッダの書き出し
    00088 void BinarySceneSaver::writeHeader(){
    00089     // フォーマットIDの書き出し
    00090     writeID("LBScene");
    00091     // バージョン番号の書き出し
    00092     u_int binaryVersion = 0x00000900;
    00093     writer_->writeUInt(binaryVersion);
    00094     align();
    00095 }
    00096 //------------------------------------------------------------------------------
    00097 // オブジェクトリストの書き出し
    00098 int BinarySceneSaver::writeObjectList(){
    00099     int linkCount = 0;
    00100     // フォグの書き出し
    00101     writeFog(scene_->getFog());
    00102     // フォグはリンクされないのでカウントしない
    00103
    00104     // シーンノードリストの書き出し
    00105     int sceneNodeCount = sceneNodeManager_->getCount();
    00106     // ルートノードは出力しないので2以上
    00107     if(sceneNodeCount > 1){ writeSceneNodeList(); }
    00108     linkCount += sceneNodeCount;
    00109
    00110     // ライトリストの書き出し
    00111     int lightCount = lightManager_->getCount();
    00112     if(lightCount > 0){ writeLightList(); }
    00113     // ライトはリンクされないのでカウントしない
    00114
    00115     // モデルリストの書き出し
    00116     int modelCount = modelManager_->getCount();
    00117     if(modelCount > 0){ writeModelList(); }
    00118     linkCount += modelCount;
    00119
    00120     // メッシュリストの書き出し
    00121     int meshCount = meshManager_->getCount();
    00122     if(meshCount > 0){ writeMeshList(); }
    00123     linkCount += meshCount;
    00124
    00125     // メッシュデータリストの書き出し
    00126     int meshDataCount = meshDataManager_->getCount();
    00127     if(meshDataCount > 0){ writeMeshDataList(); }
    00128     linkCount += meshDataCount;
    00129
    00130     // マテリアルリストの書き出し
    00131     int materialCount = materialManager_->getCount();
    00132     if(materialCount > 0){ writeMaterialList(); }
    00133     linkCount += materialCount;
    00134
    00135     // テクスチャリストの書き出し
    00136     int textureCount = textureManager_->getCount();
    00137     if(textureCount > 0){ writeTextureList(); }
    00138     linkCount += textureCount;
    00139
    00140     // ピクチャリストの書き出し
    00141     int pictureCount = pictureManager_->getCount();
    00142     if(pictureCount > 0){
    00143         int startAddress = startBlock("Picture");
    00144         for(int i = 0; i < pictureCount; i++){
    00145             writePicture(pictureManager_->get(i));
    00146         }
    00147         endBlock(startAddress);
    00148     }
    00149     linkCount += pictureCount;
    00150
    00151     return linkCount;
    00152 }
    00153 //------------------------------------------------------------------------------
    00154 // リンクの書き出し
    00155 void BinarySceneSaver::writeLink(int linkCount){
    00156     // オブジェクトが1個以下ならリンクは存在しない
    00157     if(linkCount <= 1){ return; }
    00158
    00159     { // シーンノードリンクの書き出し
    00160         int startAddress = startBlock("SceneNodeLin");
    00161         int sceneNodeCount = sceneNodeManager_->getCount();
    00162         for(int i = 0; i < sceneNodeCount; i++){
    00163             writeSceneNodeLink(sceneNodeManager_->get(i));
    00164         }
    00165         endBlock(startAddress);
    00166     }
    00167
    00168     // モデルリンクの書き出し
    00169     int modelCount = modelManager_->getCount();
    00170     if(modelCount > 0){
    00171         int startAddress = startBlock("ModelLink");
    00172         for(int i = 0; i < modelCount; i++){
    00173             writeModelLink(modelManager_->get(i));
    00174         }
    00175         endBlock(startAddress);
    00176     }
    00177
    00178     // メッシュリンクの書き出し
    00179     int meshCount = meshManager_->getCount();
    00180     if(meshCount > 0){
    00181         int startAddress = startBlock("MeshLink");
    00182         for(int i = 0; i < meshCount; i++){
    00183             writeMeshLink(meshManager_->get(i));
    00184         }
    00185         endBlock(startAddress);
    00186     }
    00187
    00188     // マテリアルテクスチャリンクの書き出し
    00189     // テクスチャが存在すればマテリアルからのリンクがある
    00190     int textureCount = textureManager_->getCount();
    00191     if(textureCount > 0){ writeMaterialLinkList(); }
    00192
    00193     // テクスチャリンクの書き出し
    00194     if(textureCount > 0){
    00195         int startAddress = startBlock("TextureLink");
    00196         for(int i = 0; i < textureCount; i++){
    00197             writeTextureLink(textureManager_->get(i));
    00198         }
    00199         endBlock(startAddress);
    00200     }
    00201 }
    00202 //------------------------------------------------------------------------------
    00203 // フォグ
    00204 //------------------------------------------------------------------------------
    00205 // フォグの書き出し
    00206 void BinarySceneSaver::writeFog(Fog* fog){
    00207     int startAddress = startBlock("Fog");
    00208     // カラー
    00209     writeColor4c(fog->getColor());
    00210     // モード
    00211     writer_->writeInt(fog->getMode());
    00212     // 濃度
    00213     writer_->writeFloat(fog->getDensity());
    00214     // ニア
    00215     writer_->writeFloat(fog->getNear());
    00216     // ファー
    00217     writer_->writeFloat(fog->getFar());
    00218     // 有効、無効
    00219     writer_->writeBool(fog->isEnabled());
    00220     endBlock(startAddress);
    00221 }
    00222 //------------------------------------------------------------------------------
    00223 // シーンノード
    00224 //------------------------------------------------------------------------------
    00225 // シーンノードリストの書き出し
    00226 void BinarySceneSaver::writeSceneNodeList(){
    00227     int startAddress = startBlock("SceneNode");
    00228     int sceneNodeCount = sceneNodeManager_->getCount();
    00229     // ルートノードは出力しない
    00230     for(int i = 1; i < sceneNodeCount; i++){
    00231         SceneNode* sceneNode = sceneNodeManager_->get(i);
    00232         if(sceneNode->isLODSceneNode()){
    00233             writeLODSceneNode(sceneNode->castLODSceneNode());
    00234         }else{
    00235             writeSceneNode(sceneNode);
    00236         }
    00237     }
    00238     endBlock(startAddress);
    00239 }
    00240 //------------------------------------------------------------------------------
    00241 // シーンノードの書き出し
    00242 void BinarySceneSaver::writeSceneNode(SceneNode* sceneNode){
    00243     int startAddress = startBlock("Standard");
    00244     // 名前
    00245     writeString(sceneNode->getName());
    00246     // スケール
    00247     writeVector3(sceneNode->getScale());
    00248     // 回転
    00249     writeVector3(sceneNode->getRotationXYZ());
    00250     // 移動
    00251     writeVector3(sceneNode->getTranslation());
    00252     // 有効、無効
    00253     writer_->writeBool(sceneNode->isEnabled());
    00254     endBlock(startAddress);
    00255 }
    00256 //------------------------------------------------------------------------------
    00257 // レベルオブディティールシーンノードの書き出し
    00258 void BinarySceneSaver::writeLODSceneNode(LODSceneNode* sceneNode){
    00259     int startAddress = startBlock("LOD");
    00260     // 名前
    00261     writeString(sceneNode->getName());
    00262     // スケール
    00263     writeVector3(sceneNode->getScale());
    00264     // 回転
    00265     writeVector3(sceneNode->getRotationXYZ());
    00266     // 移動
    00267     writeVector3(sceneNode->getTranslation());
    00268     // LOD分割数
    00269     int lodThresholdCount = sceneNode->getLODThresholdCount();
    00270     writer_->writeInt(lodThresholdCount);
    00271     for(int i = 0; i < lodThresholdCount; i++){
    00272         writer_->writeFloat(sceneNode->getLODThreshold(i));
    00273     }
    00274     // 有効、無効
    00275     writer_->writeBool(sceneNode->isEnabled());
    00276     endBlock(startAddress);
    00277 }
    00278 //------------------------------------------------------------------------------
    00279 // ライト
    00280 //------------------------------------------------------------------------------
    00281 // ライトリストの書き出し
    00282 void BinarySceneSaver::writeLightList(){
    00283     int startAddress = startBlock("Light");
    00284     int lightCount = lightManager_->getCount();
    00285     for(int i = 0; i < lightCount; i++){
    00286         Light* light = lightManager_->get(i);
    00287         if(light->isAmbientLight()){
    00288             writeAmbientLight(light->castAmbientLight());
    00289         }else if(light->isDirectionalLight()){
    00290             writeDirectionalLight(light->castDirectionalLight());
    00291         }else if(light->isPointLight()){
    00292             writePointLight(light->castPointLight());
    00293         }else{
    00294             ErrorOut("BinarySceneSaver::writeLightList() unsupported light %s",
    00295                 light->getName().getBytes());
    00296         }
    00297     }
    00298     endBlock(startAddress);
    00299 }
    00300 //------------------------------------------------------------------------------
    00301 // ライトの書き出し
    00302 void BinarySceneSaver::writeLight(Light* light){
    00303     // ライトマスク
    00304     writer_->writeUInt(light->getLightMask());
    00305     // 有効、無効
    00306     writer_->writeBool(light->isEnabled());
    00307 }
    00308 //------------------------------------------------------------------------------
    00309 // アンビエントライトの書き出し
    00310 void BinarySceneSaver::writeAmbientLight(AmbientLight* light){
    00311     int startAddress = startBlock("Ambient");
    00312     // 名前
    00313     writeString(light->getName());
    00314     // カラー
    00315     writeColor3f(light->getColor());
    00316     // ライトの書き出し
    00317     writeLight(light);
    00318     endBlock(startAddress);
    00319 }
    00320 //------------------------------------------------------------------------------
    00321 // ディレクショナルライトの書き出し
    00322 void BinarySceneSaver::writeDirectionalLight(DirectionalLight* light){
    00323     int startAddress = startBlock("Directional");
    00324     // 名前
    00325     writeString(light->getName());
    00326     // ディフューズカラー
    00327     writeColor3f(light->getDiffuseColor());
    00328     // スペキュラカラー
    00329     writeColor3f(light->getSpecularColor());
    00330     // 方向
    00331     writeVector3(light->getDirection());
    00332     // ライトの書き出し
    00333     writeLight(light);
    00334     endBlock(startAddress);
    00335 }
    00336 //------------------------------------------------------------------------------
    00337 // ポイントライトの書き出し
    00338 void BinarySceneSaver::writePointLight(PointLight* light){
    00339     int startAddress = startBlock("Point");
    00340     // 名前
    00341     writeString(light->getName());
    00342     // ディフューズカラー
    00343     writeColor3f(light->getDiffuseColor());
    00344     // スペキュラカラー
    00345     writeColor3f(light->getSpecularColor());
    00346     // 位置
    00347     writeVector3(light->getPosition());
    00348     // レンジ
    00349     writer_->writeFloat(light->getRange());
    00350     // 減衰係数
    00351     writer_->writeFloat(light->getAttenuation0());
    00352     writer_->writeFloat(light->getAttenuation1());
    00353     writer_->writeFloat(light->getAttenuation2());
    00354     // ライトの書き出し
    00355     writeLight(light);
    00356     endBlock(startAddress);
    00357 }
    00358 //------------------------------------------------------------------------------
    00359 // モデル
    00360 //------------------------------------------------------------------------------
    00361 // モデルリストの書き出し
    00362 void BinarySceneSaver::writeModelList(){
    00363     int startAddress = startBlock("Model");
    00364     int modelCount = modelManager_->getCount();
    00365     for(int i = 0; i < modelCount; i++){
    00366         Model* model = modelManager_->get(i);
    00367         if(model->isStandardModel()){
    00368             writeStandardModel(model->castStandardModel());
    00369         }else if(model->isCharacterModel()){
    00370             writeCharacterModel(model->castCharacterModel());
    00371         }else{
    00372             ErrorOut("BinarySceneSaver::writeModelList() "
    00373                 "unsupported model %s", model->getName().getBytes());
    00374         }
    00375     }
    00376     endBlock(startAddress);
    00377 }
    00378 //------------------------------------------------------------------------------
    00379 // 標準モデルの書き出し
    00380 void BinarySceneSaver::writeStandardModel(StandardModel* model){
    00381     int startAddress = startBlock("Standard");
    00382     // 名前
    00383     writeString(model->getName());
    00384     // 有効、無効
    00385     writer_->writeBool(model->isEnabled());
    00386     endBlock(startAddress);
    00387 }
    00388 //------------------------------------------------------------------------------
    00389 // キャラクタモデルの書き出し
    00390 void BinarySceneSaver::writeCharacterModel(CharacterModel* model){
    00391     int startAddress = startBlock("Character");
    00392     // 名前
    00393     writeString(model->getName());
    00394     // 有効、無効
    00395     writer_->writeBool(model->isEnabled());
    00396     // アライメント
    00397     align();
    00398     // ボーンの書き出し
    00399     int boneCount = model->getBoneCount();
    00400     writer_->writeInt(boneCount);
    00401     for(int i = 0; i < boneCount; i++){ writeBone(model->getBone(i)); }
    00402     // ボーンリンクの書き出し
    00403     for(int i = 0; i < boneCount; i++){
    00404         writeBoneLink(model, model->getBone(i));
    00405     }
    00406     endBlock(startAddress);
    00407 }
    00408 //------------------------------------------------------------------------------
    00409 // ボーンの書き出し
    00410 void BinarySceneSaver::writeBone(Bone* bone){
    00411     // 名前
    00412     writeString(bone->getName());
    00413     // ポーズ逆行列
    00414     writeMatrix34(bone->getInversePoseMatrix());
    00415     // スケール
    00416     writeVector3(bone->getScale());
    00417     // 回転
    00418     writeVector3(bone->getRotationXYZ());
    00419     // 移動
    00420     writeVector3(bone->getTranslation());
    00421 }
    00422 //------------------------------------------------------------------------------
    00423 // ボーンリンクの書き出し
    00424 void BinarySceneSaver::writeBoneLink(CharacterModel* model, Bone* bone){
    00425     int boneCount = bone->getBoneCount();
    00426     writer_->writeInt(boneCount);
    00427     for(int i = 0; i < boneCount; i++){
    00428         writer_->writeInt(model->getBoneIndex(bone->getBone(i)));
    00429     }
    00430 }
    00431 //------------------------------------------------------------------------------
    00432 // メッシュ
    00433 //------------------------------------------------------------------------------
    00434 // メッシュリストの書き出し
    00435 void BinarySceneSaver::writeMeshList(){
    00436     int startAddress = startBlock("Mesh");
    00437     int meshCount = meshManager_->getCount();
    00438     for(int i = 0; i < meshCount; i++){
    00439         Mesh* mesh = meshManager_->get(i);
    00440         if(mesh->isRigidMesh()){
    00441             writeRigidMesh(mesh->castRigidMesh());
    00442         }else if(mesh->isCharacterMesh()){
    00443             writeCharacterMesh(mesh->castCharacterMesh());
    00444         }else{
    00445             ErrorOut("BinarySceneSaver::writeMeshList() unsupported mesh %s",
    00446                 mesh->getName().getBytes());
    00447         }
    00448     }
    00449     endBlock(startAddress);
    00450 }
    00451 //------------------------------------------------------------------------------
    00452 // 剛体メッシュの書き出し
    00453 void BinarySceneSaver::writeRigidMesh(RigidMesh* mesh){
    00454     int startAddress = startBlock("Rigid");
    00455     // 名前
    00456     writeString(mesh->getName());
    00457     // 有効、無効
    00458     writer_->writeBool(mesh->isEnabled());
    00459     endBlock(startAddress);
    00460 }
    00461 //------------------------------------------------------------------------------
    00462 // キャラクタメッシュの書き出し
    00463 void BinarySceneSaver::writeCharacterMesh(CharacterMesh* mesh){
    00464     int startAddress = startBlock("Character");
    00465     // 名前
    00466     writeString(mesh->getName());
    00467     // 有効、無効
    00468     writer_->writeBool(mesh->isEnabled());
    00469     endBlock(startAddress);
    00470 }
    00471 //------------------------------------------------------------------------------
    00472 // メッシュデータ
    00473 //------------------------------------------------------------------------------
    00474 // メッシュデータリストの書き出し
    00475 void BinarySceneSaver::writeMeshDataList(){
    00476     int startAddress = startBlock("MeshData");
    00477     int meshDataCount = meshDataManager_->getCount();
    00478     for(int i = 0; i < meshDataCount; i++){
    00479         writeMeshData(meshDataManager_->get(i));
    00480     }
    00481     endBlock(startAddress);
    00482 }
    00483 //------------------------------------------------------------------------------
    00484 // メッシュデータの書き出し
    00485 void BinarySceneSaver::writeMeshData(MeshData* meshData){
    00486     // 名前
    00487     writeString(meshData->getName());
    00488     // バウンディングボックス
    00489     writeAxisAlignedBox(meshData->getBoundingBox());
    00490     // バウンディングスフィア
    00491     writeSphere(meshData->getBoundingSphere());
    00492     // プリミティブタイプ
    00493     writer_->writeInt(meshData->getPrimitiveType());
    00494     // インデックス出力
    00495     int vertexIndexCount = meshData->getVertexIndexCount();
    00496     writer_->writeInt(vertexIndexCount);
    00497     if(vertexIndexCount > 0){
    00498         writer_->writeBytes(meshData->getVertexIndexArray(),
    00499             sizeof(u_short) * vertexIndexCount);
    00500     }
    00501     // 法線を持っているか
    00502     bool hasNormal = meshData->hasNormal();
    00503     writer_->writeBool(hasNormal);
    00504     // 頂点カラーを持っているか
    00505     bool hasColor = meshData->hasColor();
    00506     writer_->writeBool(hasColor);
    00507     // アライメント
    00508     align();
    00509     // 頂点数
    00510     int vertexCount = meshData->getVertexCount();
    00511     writer_->writeInt(vertexCount);
    00512     // テクスチャ座標セット数
    00513     int texCoordSetCount = meshData->getTexCoordSetCount();
    00514     writer_->writeInt(texCoordSetCount);
    00515     // テクスチャ座標タイプ
    00516     for(int i = 0; i < texCoordSetCount; i++){
    00517         int texCoordType = meshData->getTexCoordType(i);
    00518         writer_->writeInt(texCoordType);
    00519     }
    00520     // 位置
    00521     writer_->writeBytes(meshData->getPositionArray(),
    00522         sizeof(Vector3) * vertexCount);
    00523     // 法線
    00524     if(hasNormal){
    00525         writer_->writeBytes(meshData->getNormalArray(),
    00526             sizeof(Vector3) * vertexCount);
    00527     }
    00528     // 頂点カラー
    00529     if(hasColor){
    00530         writer_->writeBytes(meshData->getColorArray(),
    00531             sizeof(Color4c) * vertexCount);
    00532     }
    00533     // テクスチャ座標
    00534     for(int i = 0; i < texCoordSetCount; i++){
    00535         writer_->writeBytes(meshData->getTexCoordArray(i),
    00536             meshData->getTexCoordArraySize(i));
    00537     }
    00538     // 頂点あたりボーン数
    00539     int bonesPerVertex = meshData->getBonesPerVertex();
    00540     writer_->writeInt(bonesPerVertex);
    00541     if(bonesPerVertex != 0){
    00542         // ボーンインデックス
    00543         writer_->writeBytes(meshData->getBoneIndexArray(),
    00544             sizeof(u_char) * vertexCount * bonesPerVertex);
    00545     }
    00546     // 頂点あたりウェイト数
    00547     int weightsPerVertex = meshData->getWeightsPerVertex();
    00548     if(weightsPerVertex != 0){
    00549         // ウェイト
    00550         writer_->writeBytes(meshData->getWeightArray(),
    00551             sizeof(float) * vertexCount * weightsPerVertex);
    00552     }
    00553     // アライメント
    00554     align();
    00555 }
    00556 //------------------------------------------------------------------------------
    00557 // マテリアル
    00558 //------------------------------------------------------------------------------
    00559 // マテリアルリストの書き出し
    00560 void BinarySceneSaver::writeMaterialList(){
    00561     int startAddress = startBlock("Material");
    00562     int materialCount = materialManager_->getCount();
    00563     for(int i = 0; i < materialCount; i++){
    00564         Material* material = materialManager_->get(i);
    00565         if(material->isBasicMaterial()){
    00566             writeBasicMaterial(material->castBasicMaterial());
    00567         }else{
    00568             ErrorOut("BinarySceneSaver::writeMaterialList() "
    00569                 "unsupported material %s", material->getName().getBytes());
    00570         }
    00571     }
    00572     endBlock(startAddress);
    00573 }
    00574 //------------------------------------------------------------------------------
    00575 // マテリアルの書き出し
    00576 void BinarySceneSaver::writeMaterial(const Material* material){
    00577     // 名前
    00578     writeString(material->getName());
    00579     // 優先度
    00580     writer_->writeInt(material->getPriority());
    00581     // ブレンドモード
    00582     writer_->writeInt(material->getBlendMode());
    00583     // アルファ値
    00584     writer_->writeFloat(material->getAlpha());
    00585     // ブレンドソース
    00586     writer_->writeInt(material->getBlendSource());
    00587     // ブレンドデスティネーション
    00588     writer_->writeInt(material->getBlendDestination());
    00589     // フォグオプション
    00590     writer_->writeInt(material->getFogOption());
    00591     // ライトマスク
    00592     writer_->writeUInt(material->getLightMask());
    00593     // Z書き込み
    00594     writer_->writeBool(material->useZWrite());
    00595     // Zテスト
    00596     writer_->writeBool(material->useZTest());
    00597     // アライメント
    00598     align();
    00599 }
    00600 //------------------------------------------------------------------------------
    00601 // 基本マテリアルの書き出し
    00602 void BinarySceneSaver::writeBasicMaterial(const BasicMaterial* material){
    00603     int startAddress = startBlock("Basic");
    00604     // マテリアルの書き出し
    00605     writeMaterial(material);
    00606     // ベースUVインデックス
    00607     writer_->writeInt(material->getBaseUVIndex());
    00608     // 光沢UVインデックス
    00609     writer_->writeInt(material->getGlossUVIndex());
    00610     // ライトUVインデックス
    00611     writer_->writeInt(material->getLightUVIndex());
    00612     // 汚れUVインデックス
    00613     writer_->writeInt(material->getStainUVIndex());
    00614     // ディフューズ色
    00615     writeColor3f(material->getDiffuseColor());
    00616     // スペキュラ色
    00617     writeColor3f(material->getSpecularColor());
    00618     // スペキュラパワー
    00619     writer_->writeFloat(material->getSpecularPower());
    00620     // アンビエント色
    00621     writeColor3f(material->getAmbientColor());
    00622     // エミッシブ
    00623     writeColor3f(material->getEmissiveColor());
    00624     // アライメント
    00625     align();
    00626     endBlock(startAddress);
    00627 }
    00628 //------------------------------------------------------------------------------
    00629 // テクスチャ
    00630 //------------------------------------------------------------------------------
    00631 // テクスチャリストの書き出し
    00632 void BinarySceneSaver::writeTextureList(){
    00633     int startAddress = startBlock("Texture");
    00634     int textureCount = textureManager_->getCount();
    00635     for(int i = 0; i < textureCount; i++){
    00636         Texture* texture = textureManager_->get(i);
    00637         if(texture->isSurfaceTexture()){
    00638             writeSurfaceTexture(texture->castSurfaceTexture());
    00639         }else{
    00640             ErrorOut("BinarySceneSaver::writeTextureList() "
    00641                 "unsupported texture %s", texture->getName().getBytes());
    00642         }
    00643     }
    00644     endBlock(startAddress);
    00645 }
    00646 //------------------------------------------------------------------------------
    00647 // サーフェーステクスチャの書き出し
    00648 void BinarySceneSaver::writeSurfaceTexture(const SurfaceTexture* texture){
    00649     int startAddress = startBlock("Surface");
    00650     // 名前
    00651     writeString(texture->getName());
    00652     // アドレスモードU
    00653     writer_->writeInt(texture->getAddressModeU());
    00654     // アドレスモードV
    00655     writer_->writeInt(texture->getAddressModeV());
    00656     // リピートUV
    00657     writeTexCoord2(texture->getRepeatUV());
    00658     // オフセットUV
    00659     writeTexCoord2(texture->getOffsetUV());
    00660     endBlock(startAddress);
    00661 }
    00662 //------------------------------------------------------------------------------
    00663 // ピクチャ
    00664 //------------------------------------------------------------------------------
    00665 // ピクチャの書き出し
    00666 void BinarySceneSaver::writePicture(const Picture* picture){
    00667     // 名前
    00668     writeString(picture->getName());
    00669     // パス
    00670     String path = picture->getPath();
    00671     writeString(path);
    00672     // ピクチャ出力ディレクトリの作成
    00673     FilePath filePath(path);
    00674     path = filePath.getFolderPath();
    00675     if(path != ""){
    00676         path = basePath_ + path;
    00677         mkdir(path.getBytes());
    00678     }
    00679     // ピクチャファイルの保存
    00680     TargaSaver saver;
    00681     if(picture->isPictureRGB8()){
    00682         // RGB8は24bitのTargaで保存
    00683         PictureRGB8* rgb8 = picture->castPictureRGB8();
    00684         saver.save(basePath_ + rgb8->getPath(),
    00685             rgb8->getSize(), rgb8->getImage());
    00686     }else if(picture->isPictureRGBA8()){
    00687         // RGBA8は32bitのTargaで保存
    00688         PictureRGBA8* rgba8 = picture->castPictureRGBA8();
    00689         saver.save(basePath_ + rgba8->getPath(),
    00690             rgba8->getSize(), rgba8->getImage());
    00691     }else{
    00692         ErrorOut("BinarySceneSaver::writePictureList() "
    00693             "unsupported picture %s", picture->getName().getBytes());
    00694     }
    00695 }
    00696 //------------------------------------------------------------------------------
    00697 // リンク
    00698 //------------------------------------------------------------------------------
    00699 // シーンノードリンクの書き出し
    00700 void BinarySceneSaver::writeSceneNodeLink(SceneNode* sceneNode){
    00701     // リンクが0かどうかチェック
    00702     int sceneNodeCount = sceneNode->getSceneNodeCount();
    00703     int sceneLeafCount = sceneNode->getSceneLeafCount();
    00704     if(sceneNodeCount + sceneLeafCount == 0){ return; }
    00705     // 名前
    00706     writeString(sceneNode->getName());
    00707     // シーンノードリンク数
    00708     writer_->writeInt(sceneNodeCount);
    00709     // シーンノードリンク
    00710     for(int i = 0; i < sceneNodeCount; i++){
    00711         writeString(sceneNode->getSceneNode(i)->getName());
    00712     }
    00713     // シーンリーフリンク数
    00714     writer_->writeInt(sceneLeafCount);
    00715     // シーンリーフリンク
    00716     for(int i = 0; i < sceneLeafCount; i++){
    00717         SceneLeaf* sceneLeaf = sceneNode->getSceneLeaf(i);
    00718         if(sceneLeaf->isModel()){
    00719             writer_->writeInt(0);
    00720         }else if(sceneLeaf->isLight()){
    00721             writer_->writeInt(1);
    00722         }else{
    00723             Assert(false);
    00724         }
    00725         writeString(sceneLeaf->getName());
    00726     }
    00727 }
    00728 //------------------------------------------------------------------------------
    00729 // モデルリンクの書き出し
    00730 void BinarySceneSaver::writeModelLink(const Model* model){
    00731     int meshCount = model->getMeshCount();
    00732     if(meshCount == 0){ return; }
    00733     // 名前
    00734     writeString(model->getName());
    00735     // メッシュリンク数
    00736     writer_->writeInt(meshCount);
    00737     // メッシュリンク
    00738     for(int i = 0; i < meshCount; i++){
    00739         writeString(model->getMesh(i)->getName());
    00740     }
    00741 }
    00742 //------------------------------------------------------------------------------
    00743 // メッシュリンクの書き出し
    00744 void BinarySceneSaver::writeMeshLink(const Mesh* mesh){
    00745     bool hasMeshData = (mesh->getMeshData() != NULL);
    00746     bool hasMaterial = (mesh->getMaterial() != NULL);
    00747     if((!hasMeshData) && (!hasMaterial)){ return; }
    00748     // 名前
    00749     writeString(mesh->getName());
    00750     // メッシュデータを持つか
    00751     writer_->writeBool(hasMeshData);
    00752     // マテリアルを持つか
    00753     writer_->writeBool(hasMaterial);
    00754     // アライメント
    00755     align();
    00756     // メッシュデータ
    00757     if(hasMeshData){ writeString(mesh->getMeshData()->getName()); }
    00758     // マテリアル
    00759     if(hasMaterial){ writeString(mesh->getMaterial()->getName()); }
    00760 }
    00761 //------------------------------------------------------------------------------
    00762 // マテリアルリンクリストの書き出し
    00763 void BinarySceneSaver::writeMaterialLinkList(){
    00764     int startAddress = startBlock("MaterialLink");
    00765     int materialCount = materialManager_->getCount();
    00766     for(int i = 0; i < materialCount; i++){
    00767         Material* material = materialManager_->get(i);
    00768         if(material->isBasicMaterial()){
    00769             writeBasicMaterialLink(material->castBasicMaterial());
    00770         }else{
    00771             ErrorOut("BinarySceneSaver::writeMaterialLinkList() "
    00772                 "unsupported material %s", material->getName().getBytes());
    00773         }
    00774     }
    00775     endBlock(startAddress);
    00776 }
    00777 //------------------------------------------------------------------------------
    00778 // 基本マテリアルリンクの書き出し
    00779 void BinarySceneSaver::writeBasicMaterialLink(const BasicMaterial* material){
    00780     Texture* baseTexture = material->getBaseTexture();
    00781     Texture* glossTexture = material->getGlossTexture();
    00782     Texture* lightTexture = material->getLightTexture();
    00783     Texture* stainTexture = material->getStainTexture();
    00784     bool hasBaseTexture = (baseTexture != NULL);
    00785     bool hasGlossTexture = (glossTexture != NULL);
    00786     bool hasLightTexture = (lightTexture != NULL);
    00787     bool hasStainTexture = (stainTexture != NULL);
    00788     // テクスチャの有無をチェック
    00789     if((!hasBaseTexture) && (!hasGlossTexture) &&
    00790         (!hasLightTexture) && (!hasStainTexture)){ return; }
    00791     int startAddress = startBlock("Basic");
    00792     // 名前
    00793     writeString(material->getName());
    00794     // テクスチャの有無
    00795     writer_->writeBool(hasBaseTexture);
    00796     writer_->writeBool(hasGlossTexture);
    00797     writer_->writeBool(hasLightTexture);
    00798     writer_->writeBool(hasStainTexture);
    00799     // アライメント
    00800     align();
    00801     // テクスチャ名
    00802     if(hasBaseTexture){ writeString(baseTexture->getName()); }
    00803     if(hasGlossTexture){ writeString(glossTexture->getName()); }
    00804     if(hasLightTexture){ writeString(lightTexture->getName()); }
    00805     if(hasStainTexture){ writeString(stainTexture->getName()); }
    00806     endBlock(startAddress);
    00807 }
    00808 //------------------------------------------------------------------------------
    00809 // テクスチャリンクの書き出し
    00810 void BinarySceneSaver::writeTextureLink(const Texture* texture){
    00811     int pictureCount = texture->getPictureCount();
    00812     if(pictureCount == 0){ return; }
    00813     // 名前
    00814     writeString(texture->getName());
    00815     // ピクチャ数
    00816     writer_->writeInt(pictureCount);
    00817     // ピクチャリンク
    00818     for(int i = 0; i < pictureCount; i++){
    00819         writeString(texture->getPicture(i)->getName());
    00820     }
    00821 }
    00822 //------------------------------------------------------------------------------
    00823 // 値の書き出し
    00824 //------------------------------------------------------------------------------
    00825 // 文字列の書き出し
    00826 void BinarySceneSaver::writeString(const String& string){
    00827     int writeSize = string.getSize() + 1;
    00828     writer_->writeInt(writeSize);
    00829     writer_->writeBytes(string.getBytes(), writeSize);
    00830     align();
    00831 }
    00832 //------------------------------------------------------------------------------
    00833 // 三次元ベクトルの書き出し
    00834 void BinarySceneSaver::writeVector3(const Vector3& vector){
    00835     writer_->writeBytes(vector.array, sizeof(Vector3));
    00836 }
    00837 //------------------------------------------------------------------------------
    00838 // 3×4行列の書き出し
    00839 void BinarySceneSaver::writeMatrix34(const Matrix34& matrix){
    00840     writer_->writeBytes(matrix.array, sizeof(Matrix34));
    00841 }
    00842 //------------------------------------------------------------------------------
    00843 // 四要素整数カラー値の書き出し
    00844 void BinarySceneSaver::writeColor4c(const Color4c& color){
    00845     writer_->writeBytes(color.array, sizeof(Color4c));
    00846 }
    00847 //------------------------------------------------------------------------------
    00848 // 三要素実数カラー値の書き出し
    00849 void BinarySceneSaver::writeColor3f(const Color3f& color){
    00850     writer_->writeBytes(color.array, sizeof(Color3f));
    00851 }
    00852 //------------------------------------------------------------------------------
    00853 // 四要素実数カラー値の書き出し
    00854 void BinarySceneSaver::writeColor4f(const Color4f& color){
    00855     writer_->writeBytes(color.array, sizeof(Color4f));
    00856 }
    00857 //------------------------------------------------------------------------------
    00858 // 二次元テクスチャ座標値の書き出し
    00859 void BinarySceneSaver::writeTexCoord2(const TexCoord2& uv){
    00860     writer_->writeBytes(uv.array, sizeof(TexCoord2));
    00861 }
    00862 //------------------------------------------------------------------------------
    00863 // 軸沿いボックスの書き出し
    00864 void BinarySceneSaver::writeAxisAlignedBox(const AxisAlignedBox& box){
    00865     writer_->writeBytes(&box, sizeof(AxisAlignedBox));
    00866 }
    00867 //------------------------------------------------------------------------------
    00868 // 球の書き出し
    00869 void BinarySceneSaver::writeSphere(const Sphere& sphere){
    00870     writer_->writeBytes(&sphere, sizeof(Sphere));
    00871 }
    00872 //------------------------------------------------------------------------------
    00873 // ユーティリティ
    00874 //------------------------------------------------------------------------------
    00875 // アライメントを取る
    00876 void BinarySceneSaver::align(){
    00877     writer_->align(16);
    00878 }
    00879 //------------------------------------------------------------------------------
    00880 // IDの書き出し
    00881 void BinarySceneSaver::writeID(const String& id){
    00882     u_char buffer[12];
    00883     int size = id.getSize();
    00884     Assert(size <= 12);
    00885     for(int i = 0; i < size; i++){ buffer[i] = id.charAt(i); }
    00886     for(int i = size; i < 12; i++){ buffer[i] = 0; }
    00887     writer_->writeBytes(buffer, 12);
    00888 }
    00889 //------------------------------------------------------------------------------
    00890 // ブロックの開始
    00891 int BinarySceneSaver::startBlock(const String& blockName){
    00892     writeID(blockName);
    00893     u_int blockAddress = writer_->getPosition();
    00894     // サイズの予約
    00895     writer_->writeInt(0);
    00896     align();
    00897     return blockAddress;
    00898 }
    00899 //------------------------------------------------------------------------------
    00900 // ブロックの終了
    00901 void BinarySceneSaver::endBlock(int blockStartAddress){
    00902     align();
    00903     int nowPosition = writer_->getPosition();
    00904     // サイズ分をブロックサイズから引く
    00905     int blockSize = nowPosition - blockStartAddress - 4;// アライメント依存
    00906     writer_->setPosition(blockStartAddress);
    00907     writer_->writeInt(blockSize);
    00908     writer_->setPosition(nowPosition);
    00909 }
    00910 //------------------------------------------------------------------------------
    00911 } // End of namespace Lamp
    00912 //------------------------------------------------------------------------------