OSGOFRecords.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *                Copyright (C) 2008 by the OpenSG Forum                     *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 #include "OSGOFRecords.h"
00040
00041 #include "OSGSingletonHolder.ins"
00042
00043 #include "OSGGroup.h"
00044 #include "OSGRangeLOD.h"
00045 #include "OSGTransform.h"
00046 #include "OSGGeometry.h"
00047 #include "OSGTypedGeoIntegralProperty.h"
00048 #include "OSGOFDatabase.h"
00049
00050 #include "OSGImageFileHandler.h"
00051 #include "OSGSceneFileHandler.h"
00052
00053 #include "OSGChunkMaterial.h"
00054 #include "OSGBlendChunk.h"
00055 #include "OSGDepthChunk.h"
00056 #include "OSGPolygonChunk.h"
00057 #include "OSGTextureEnvChunk.h"
00058
00059 #include "OSGGeoFunctions.h"
00060
00061 #include "OSGOpenFlightSceneFileType.h"
00062
00063 OSG_BEGIN_NAMESPACE
00064
00065 OSG_SINGLETON_INST(OFRecordFactoryBase, addPostFactoryExitFunction)
00066
00067 template class SingletonHolder<OFRecordFactoryBase>;
00068
00069 // constants for Faces and Meshes
00070 // TODO: maybe these should be members of a common base class ? -- cneumann
00071 namespace
00072 {
00073     // Flags
00074     const Int32  FlagTerrain             = 0x80000000;
00075     const Int32  FlagNoColor             = 0x40000000;
00076     const Int32  FlagNoAltColor          = 0x20000000;
00077     const Int32  FlagPackedColor         = 0x10000000;
00078     const Int32  FlagTerrainFootprint    = 0x08000000;
00079     const Int32  FlagHidden              = 0x04000000;
00080     const Int32  FlagRoofline            = 0x02000000;
00081
00082     // DrawType constants
00083     const Int8   DTSolidCullBack         =  0;
00084     const Int8   DTSolid                 =  1;
00085     const Int8   DTWireframeClosed       =  2;
00086     const Int8   DTWireframe             =  3;
00087     const Int8   DTWireframeSurround     =  4;
00088     const Int8   DTOmnidirectionalLight  =  8;
00089     const Int8   DTUnidirectionalLight   =  9;
00090     const Int8   DTBidirectionalLight    = 10;
00091
00092     // LightMode constants
00093     const UInt8  LMFaceColor             =  0;  // used in FaceRecord
00094     const UInt8  LMMeshColor             =  0;  // used in MeshRecord
00095     const UInt8  LMVertexColor           =  1;
00096     const UInt8  LMFaceColorLit          =  2;  // used in FaceRecord
00097     const UInt8  LMMeshColorLit          =  2;  // used in MeshRecord
00098     const UInt8  LMVertexColorLit        =  3;
00099
00100 } // namespace
00101
00102 //---------------------------------------------------------------------
00103 // OFRecordFactoryBase
00104 //---------------------------------------------------------------------
00105
00106 OFRecordFactoryBase::RegisterRecord::RegisterRecord(CreateRecord fCreate,
00107                                                     UInt16       sRecordOpCode)
00108 {
00109     OFRecordFactory::the()->registerRecord(fCreate, sRecordOpCode);
00110 }
00111
00112
00113 OFRecordFactoryBase::OFRecordFactoryBase(void) :
00114     _mRegisteredRecords()
00115 {
00116 }
00117
00118 OFRecordFactoryBase::~OFRecordFactoryBase(void)
00119 {
00120 }
00121
00122 void OFRecordFactoryBase::registerRecord(CreateRecord fHelper,
00123                                          UInt16       sRecordOpCode)
00124 {
00125     if(fHelper == NULL)
00126         return;
00127
00128     NameRecordCreateMap::iterator mRecordIt =
00129         _mRegisteredRecords.find(sRecordOpCode);
00130
00131
00132     if(mRecordIt == _mRegisteredRecords.end())
00133     {
00134         _mRegisteredRecords[sRecordOpCode] = fHelper;
00135
00136         PINFO << "Record registered for "
00137               << sRecordOpCode
00138               << std::endl;
00139     }
00140     else
00141     {
00142         PWARNING << "Record already registered for %s "
00143                  << sRecordOpCode
00144                  << std::endl;
00145     }
00146 }
00147
00148 OFRecordTransitPtr OFRecordFactoryBase::createRecord(
00149     const OFRecordHeader &oHeader)
00150 {
00151     NameRecordCreateMap::iterator mRecordIt =
00152         _mRegisteredRecords.find(oHeader.sOpCode);
00153
00154     OFRecordTransitPtr returnValue(NULL);
00155
00156     if(mRecordIt != _mRegisteredRecords.end())
00157     {
00158         returnValue = (*mRecordIt).second(oHeader);
00159     }
00160     else
00161     {
00162         returnValue = new OFUnknownRecord(oHeader);
00163     }
00164
00165     return returnValue;
00166 }
00167
00168 //---------------------------------------------------------------------
00169 // OFRecord
00170 //---------------------------------------------------------------------
00171
00172 struct OFOpCodeDesc
00173 {
00174           UInt16  sOpCode;
00175     const Char8  *szDesc;
00176 };
00177
00178
00179 OFOpCodeDesc aOpCodeDescs[] =
00180 {
00181     {1,   "Header"                             },
00182     {2,   "Group"                              },
00183     {4,   "Object"                             },
00184     {5,   "Face"                               },
00185     {10,  "Push Level"                         },
00186     {11,  "Pop Level"                          },
00187     {14,  "Degree of Freedom"                  },
00188     {19,  "Push Subface"                       },
00189     {20,  "Pop Subface"                        },
00190     {21,  "Push Extension"                     },
00191     {22,  "Pop Extension"                      },
00192     {23,  "Continuation"                       },
00193     {31,  "Comment"                            },
00194     {32,  "Color Palette"                      },
00195     {33,  "Long ID"                            },
00196     {49,  "Matrix"                             },
00197     {50,  "Vector"                             },
00198     {52,  "Multitexture"                       },
00199     {53,  "UV List"                            },
00200     {55,  "Binary Separating Plane"            },
00201     {60,  "Replicate"                          },
00202     {61,  "Instance Reference"                 },
00203     {62,  "Instance Definition"                },
00204     {63,  "External Reference"                 },
00205     {64,  "Texture Palette"                    },
00206     {67,  "Vertex Palette"                     },
00207     {68,  "Vertex with Color"                  },
00208     {69,  "Vertex with Color and Normal"       },
00209     {70,  "Vertex with Color, Normal and UV"   },
00210     {71,  "Vertex with Color and UV"           },
00211     {72,  "Vertex List"                        },
00212     {73,  "Level of Detail"                    },
00213     {74,  "Bounding Box"                       },
00214     {76,  "Rotate About Edge"                  },
00215     {78,  "Translate"                          },
00216     {79,  "Scale"                              },
00217     {80,  "Rotate About Point"                 },
00218     {81,  "Rotate and/or Scale to Point"       },
00219     {82,  "Put"                                },
00220     {83,  "Eyepoint and Trackplane Palette"    },
00221     {84,  "Mesh"                               },
00222     {85,  "Local Vertex Pool"                  },
00223     {86,  "Mesh Primitive"                     },
00224     {87,  "Road Segment"                       },
00225     {88,  "Road Zone"                          },
00226     {89,  "Morph Vertex List"                  },
00227     {90,  "Linkage Palette"                    },
00228     {91,  "Sound"                              },
00229     {92,  "Road Path"                          },
00230     {93,  "Sound Palette"                      },
00231     {94,  "General Matrix"                     },
00232     {95,  "Text"                               },
00233     {96,  "Switch"                             },
00234     {97,  "Line Style Palette"                 },
00235     {98,  "Clip Region"                        },
00236     {100, "Extension"                          },
00237     {101, "Light Source"                       },
00238     {102, "Light Source Palette"               },
00239     {103, "Reserved"                           },
00240     {104, "Reserved"                           },
00241     {105, "Bounding Sphere"                    },
00242     {106, "Bounding Cylinder"                  },
00243     {107, "Bounding Convex Hull"               },
00244     {108, "Bounding Volume Center"             },
00245     {109, "Bounding Volume Orientation"        },
00246     {110, "Reserved"                           },
00247     {111, "Light Point"                        },
00248     {112, "Texture Mapping Palette"            },
00249     {113, "Material Palette"                   },
00250     {114, "Name Table"                         },
00251     {115, "Continuously Adaptive Terrain (CAT)"},
00252     {116, "CAT Data"                           },
00253     {117, "Reserved"                           },
00254     {118, "Reserved"                           },
00255     {119, "Bounding Histogram"                 },
00256     {120, "Reserved"                           },
00257     {121, "Reserved"                           },
00258     {122, "Push Attribute"                     },
00259     {123, "Pop Attribute"                      },
00260     {124, "Reserved"                           },
00261     {125, "Reserved"                           },
00262     {126, "Curve"                              },
00263     {127, "Road Construction"                  },
00264     {128, "Light Point Appearance Palette"     },
00265     {129, "Light Point Animation Palette"      },
00266     {130, "Indexed Light Point"                },
00267     {131, "Light Point System"                 },
00268     {132, "Indexed String"                     },
00269     {133, "Shader Palette"                     },
00270     {134, "Reserved"                           },
00271     {135, "Extended Material Header"           },
00272     {136, "Extended Material Ambient"          },
00273     {137, "Extended Material Diffuse"          },
00274     {138, "Extended Material Specular"         },
00275     {139, "Extended Material Emissive"         },
00276     {140, "Extended Material Alpha"            },
00277     {141, "Extended Material Light Map"        },
00278     {142, "Extended Material Normal Map"       },
00279     {143, "Extended Material Bump Map"         },
00280     {144, "Reserved"                           },
00281     {145, "Extended Material Shadow Map"       },
00282     {146, "Reserved"                           },
00283     {147, "Extended Material Reflection Map"   },
00284
00285     {0, "Reached last -> Unknown"              }
00286 };
00287
00288 #if 0
00289 Obsolete
00290
00291 3  Level of Detail (single precision floating point, replaced by Opcode 73)
00292 6  Vertex with ID (scaled integer coordinates, replaced by Opcodes 68-71)
00293 7  Short Vertex w/o ID (scaled integer coordinates, replaced by Opcodes 68-71)
00294 8  Vertex with Color (scaled integer coordinates, replaced by Opcodes 68-71)
00295 9  Vertex with Color and Normal (scaled integer coordinates, replaced by Opcodes 68-71)
00296 12 Translate (replaced by Opcode 78)
00297 13 Degree of Freedom (scaled integer coordinates, replaced by Opcode 14)
00298 16 Instance Reference (replaced by Opcode 61)
00299 17 Instance Definition (replaced by Opcode 62)
00300 40 Translate (replaced by Opcode 78)
00301 41 Rotate about Point (replaced by Opcode 80)
00302 42 Rotate about Edge (replaced by Opcode 76)
00303 43 Scale (replaced by Opcode 79)
00304 44 Translate (replaced by Opcode 78)
00305 45 Scale nonuniform (replaced by Opcode 79)
00306 46 Rotate about Point (replaced by Opcode 80)
00307 47 Rotate and/or Scale to Point (replaced by Opcode 81)
00308 48 Put (replaced by Opcode 82)
00309 51 Bounding Box (replaced by Opcode 74)
00310 65 Eyepoint Palette (only eyepoints, replaced by Opcode 83)
00311 66 Material Palette (fixed size 64 entries, replaced by Opcode 80)
00312 77 Scale (replaced by Opcode 79)
00313
00314 #endif
00315 
00316
00317 void OFRecord::readChar8(std::istream &is, Char8  *cVal, UInt32 iSize)
00318 {
00319     is.read(cVal, iSize);
00320 }
00321
00322 template<class ValueT>
00323 UInt32 OFRecord::readVal(std::istream &is, ValueT &val)
00324 {
00325     is.read(reinterpret_cast<char *>(&val), sizeof(ValueT));
00326
00327     val = osgBigEndianToHost(val);
00328
00329     return sizeof(ValueT);
00330 }
00331
00332 template<>
00333 UInt32 OFRecord::readVal<Int8>(std::istream &is, Int8 &val)
00334 {
00335     is.read(reinterpret_cast<char *>(&val), sizeof(Int8));
00336
00337     return sizeof(Int8);
00338 }
00339
00340 template<>
00341 UInt32 OFRecord::readVal<UInt8>(std::istream &is, UInt8 &val)
00342 {
00343     is.read(reinterpret_cast<char *>(&val), sizeof(UInt8));
00344
00345     return sizeof(UInt8);
00346 }
00347
00348 OFRecord::OFRecord(const OFRecordHeader &oHeader) :
00349      Inherited(               ),
00350     _sLength  (oHeader.sLength)
00351 {
00352 }
00353
00354 OFRecord::~OFRecord(void)
00355 {
00356 }
00357
00358 bool OFRecord::read(std::istream &is, OFDatabase &oDB)
00359 {
00360     if(_sLength > 4)
00361     {
00362         return readContinue(is, oDB, _sLength - 4);
00363     }
00364     else
00365     {
00366         return is.good();
00367     }
00368 }
00369
00370 bool OFRecord::readContinue(std::istream &is, OFDatabase &oDB, UInt16 uiLength)
00371 {
00372     std::vector<char> tmpBuf;
00373
00374     tmpBuf.resize(uiLength);
00375
00376     is.read(&(tmpBuf.front()), uiLength);
00377
00378     return is.good();
00379 }
00380
00381 bool OFRecord::addChild (OFRecord *pChild)
00382 {
00383     if(pChild == NULL)
00384         return false;
00385
00386 #if 0
00387           UInt16  uiCurrOpCode  = this  ->getOpCode(             );
00388     const Char8  *szCurrDesc    = this  ->findDesc (uiCurrOpCode );
00389           UInt16  uiChildOpCode = pChild->getOpCode(             );
00390     const Char8  *szChildDesc   = this  ->findDesc (uiChildOpCode);
00391
00392     fprintf(stderr, "Add %hu (%p) (%s) to %hu (%p) (%s)\n",
00393             uiChildOpCode,
00394             pChild,
00395             szChildDesc,
00396             uiCurrOpCode,
00397             this,
00398             szCurrDesc);
00399 #endif
00400 
00401     return true;
00402 }
00403
00404 NodeTransitPtr OFRecord::convertToNode(OFDatabase &oDB)
00405 {
00406     NodeTransitPtr returnValue(NULL);
00407
00408     return returnValue;
00409 }
00410
00411
00412 const Char8 *OFRecord::findDesc(UInt16 sOpCode)
00413 {
00414     OFOpCodeDesc *pDesc = aOpCodeDescs;
00415
00416     while(pDesc->sOpCode != 0)
00417     {
00418         if(pDesc->sOpCode == sOpCode)
00419         {
00420             break;
00421         }
00422
00423         ++pDesc;
00424     }
00425
00426     return pDesc->szDesc;
00427 }
00428
00429 void OFRecord::dump(UInt32 uiIndent)
00430 {
00431 }
00432
00433 //---------------------------------------------------------------------
00434 // OFVertexPalette
00435 //---------------------------------------------------------------------
00436
00437 OFVertexPalette::OFVertexPalette(void) :
00438      Inherited     (    ),
00439     _pVertexPalette(NULL)
00440 {
00441 }
00442
00443 OFVertexPalette::~OFVertexPalette(void)
00444 {
00445     _pVertexPalette = NULL;
00446 }
00447
00448 void OFVertexPalette::addRecord(OFVertexPaletteRecord *pVertexPal)
00449 {
00450     _pVertexPalette = pVertexPal;
00451 }
00452
00453 const OFVertexPaletteRecord *OFVertexPalette::getRecord(void)
00454 {
00455     return _pVertexPalette;
00456 }
00457
00458 void OFVertexPalette::dump(UInt32 uiIndent)
00459 {
00460     if(_pVertexPalette != NULL)
00461         _pVertexPalette->dump(uiIndent);
00462 }
00463
00464 //---------------------------------------------------------------------
00465 // OFTexturePalette
00466 //---------------------------------------------------------------------
00467
00468 OFTexturePalette::OFTexturePalette(void) :
00469     _mTextures()
00470 {
00471 }
00472
00473 OFTexturePalette::~OFTexturePalette(void)
00474 {
00475     TextureStoreIt tIt  = _mTextures.begin();
00476     TextureStoreIt tEnd = _mTextures.end  ();
00477
00478     while(tIt != tEnd)
00479     {
00480         tIt->second = NULL;
00481
00482         ++tIt;
00483     }
00484
00485     _mTextures.clear();
00486 }
00487
00488 void OFTexturePalette::addRecord(OFTexturePaletteRecord *pTex)
00489 {
00490     if(pTex != NULL)
00491     {
00492         TextureStoreIt tIt = _mTextures.find(pTex->getPatternIdx());
00493
00494         if(tIt == _mTextures.end())
00495         {
00496             _mTextures[pTex->getPatternIdx()] = pTex;
00497         }
00498         else
00499         {
00500             FFATAL(("OFTexturePalette::addRecord: Texture with idx [%d] "
00501                     "already present.\n", pTex->getPatternIdx()));
00502         }
00503     }
00504 }
00505
00506 const OFTexturePaletteRecord *OFTexturePalette::getRecord(Int32 uiId)
00507 {
00508     const OFTexturePaletteRecord *returnValue = NULL;
00509
00510     TextureStoreIt tIt = _mTextures.find(uiId);
00511
00512     if(tIt != _mTextures.end())
00513     {
00514         returnValue = tIt->second;
00515     }
00516
00517     return returnValue;
00518 }
00519
00520 void OFTexturePalette::dump(UInt32 uiIndent)
00521 {
00522     TextureStoreIt tIt  = _mTextures.begin();
00523     TextureStoreIt tEnd = _mTextures.end  ();
00524
00525     for(; tIt != tEnd; ++tIt)
00526     {
00527         tIt->second->dump(uiIndent);
00528     }
00529 }
00530
00531 //---------------------------------------------------------------------
00532 // OFMaterialPalette
00533 //---------------------------------------------------------------------
00534
00535 OFMaterialPalette::~OFMaterialPalette(void)
00536 {
00537     // nothing to do
00538 }
00539
00540 OFMaterialPalette::OFMaterialPalette(void) :
00541     Inherited  (),
00542     _mMaterials()
00543 {
00544     // nothing to do
00545 }
00546
00547 void OFMaterialPalette::addRecord(OFMaterialPaletteRecord *pMat)
00548 {
00549     if(pMat != NULL)
00550     {
00551         MaterialStoreIt mIt = _mMaterials.find(pMat->getMaterialIdx());
00552
00553         if(mIt == _mMaterials.end())
00554         {
00555             _mMaterials[pMat->getMaterialIdx()] = pMat;
00556         }
00557         else
00558         {
00559             FWARNING(("OFMaterialPalette::addRecord: Material with idx [%d] "
00560                       "already present.\n", pMat->getMaterialIdx()));
00561         }
00562     }
00563 }
00564
00565 const OFMaterialPaletteRecord *OFMaterialPalette::getRecord(Int32 uiId)
00566 {
00567     const OFMaterialPaletteRecord *returnValue = NULL;
00568
00569     MaterialStoreIt mIt = _mMaterials.find(uiId);
00570
00571     if(mIt != _mMaterials.end())
00572     {
00573         returnValue = mIt->second;
00574     }
00575
00576     return returnValue;
00577 }
00578
00579 void OFMaterialPalette::dump(UInt32 uiIndent)
00580 {
00581     indentLog(uiIndent, PLOG);
00582     PLOG << "MaterialPalette : " << std::endl;
00583
00584     indentLog(uiIndent, PLOG);
00585     PLOG << "{" << std::endl;
00586
00587     uiIndent += 2;
00588
00589     MaterialStoreIt mIt  = _mMaterials.begin();
00590     MaterialStoreIt mEnd = _mMaterials.end  ();
00591
00592     for(; mIt != mEnd; ++mIt)
00593         mIt->second->dump(uiIndent);
00594
00595     uiIndent -= 2;
00596
00597     indentLog(uiIndent, PLOG);
00598     PLOG << "}" << std::endl;
00599 }
00600
00601 //---------------------------------------------------------------------
00602 // OFHeaderRecord
00603 //---------------------------------------------------------------------
00604
00605 OFHeaderRecord::OFHeaderRecord(const OFRecordHeader &oHeader) :
00606      Inherited(oHeader),
00607     _vChildren(       )
00608 {
00609     _pVertexPal   = new OFVertexPalette  ();
00610     _pTexturePal  = new OFTexturePalette ();
00611     _pMaterialPal = new OFMaterialPalette();
00612 }
00613
00614 OFHeaderRecord::~OFHeaderRecord(void)
00615 {
00616     for(UInt32 i = 0; i < _vChildren.size(); ++i)
00617     {
00618         _vChildren[i] = NULL;
00619     }
00620
00621     _vChildren.clear();
00622
00623     _pVertexPal   = NULL;
00624     _pTexturePal  = NULL;
00625     _pMaterialPal = NULL;
00626 }
00627
00628 bool OFHeaderRecord::read(std::istream &is, OFDatabase &)
00629 {
00630     std::vector<char> tmpBuf;
00631
00632     tmpBuf.resize(_sLength);
00633
00634     is.read(&(tmpBuf.front()), _sLength - 4);
00635
00636     return is.good();
00637 }
00638
00639 bool OFHeaderRecord::addChild(OFRecord *pChild)
00640 {
00641     if(pChild == NULL)
00642     {
00643         return false;
00644     }
00645
00646     switch(pChild->getOpCode())
00647     {
00648 //         case 32: // color
00649 //         case 83: // eye trackplane
00650 //         case 90: // linkage
00651 //         case 93: // sound
00652 //         case 97: // line style
00653 //         case 102: // light source
00654 //         case 112: // tex mapping
00655 //         case 113: // material
00656 //         case 128: // lpoint app
00657 //         case 129: // lpoint anim
00658 //         case 133: // shader
00659 //         {
00660 //             FWARNING(("OFHeaderRecord::addChild: Ignoring child [%u - %s].\n",
00661 //                       pChild->getOpCode(), findDesc(pChild->getOpCode())));
00662 //             break;
00663 //         }
00664
00665         case OFTexturePaletteRecord::OpCode:
00666         {
00667             OFTexturePaletteRecord *pTex =
00668                 dynamic_cast<OFTexturePaletteRecord *>(pChild);
00669
00670             _pTexturePal->addRecord(pTex);
00671
00672             break;
00673         }
00674
00675         case OFVertexPaletteRecord::OpCode:
00676         {
00677             _pVertexPal->addRecord(
00678                 dynamic_cast<OFVertexPaletteRecord *>(pChild));
00679
00680             break;
00681         }
00682
00683         case OFMaterialPaletteRecord::OpCode:
00684         {
00685             _pMaterialPal->addRecord(
00686                 dynamic_cast<OFMaterialPaletteRecord *>(pChild));
00687             break;
00688         }
00689
00690         default:
00691         {
00692             _vChildren.push_back(pChild);
00693         }
00694     }
00695
00696     return true;
00697 }
00698
00699 UInt16 OFHeaderRecord::getOpCode(void)
00700 {
00701     return OpCode;
00702 }
00703
00704 NodeTransitPtr OFHeaderRecord::convertToNode(OFDatabase &oDB)
00705 {
00706     NodeTransitPtr returnValue(NULL);
00707
00708     if(_vChildren.size() != 0)
00709     {
00710         returnValue = Node::create();
00711
00712         returnValue->setCore(Group::create());
00713
00714         NodeTransitPtr pChild;
00715
00716         for(UInt32 i = 0; i < _vChildren.size(); ++i)
00717         {
00718             pChild = _vChildren[i]->convertToNode(oDB);
00719
00720             if(pChild != NULL)
00721             {
00722                 returnValue->addChild(pChild);
00723             }
00724             else
00725             {
00726                 FFATAL(("OFHeaderRecord::convertToNode: "
00727                         "No child for record [%u - %s].\n",
00728                         _vChildren[i]->getOpCode(),
00729                         findDesc(_vChildren[i]->getOpCode())));
00730             }
00731         }
00732     }
00733
00734     return returnValue;
00735 }
00736
00737 const OFVertexPaletteRecord *OFHeaderRecord::getVertexPalette(void)
00738 {
00739     return _pVertexPal->getRecord();
00740 }
00741
00742 const OFTexturePaletteRecord *OFHeaderRecord::getTexRecord(UInt32 uiIdx)
00743 {
00744     return _pTexturePal->getRecord(uiIdx);
00745 }
00746
00747 const OFMaterialPaletteRecord *OFHeaderRecord::getMatRecord(UInt32 uiIdx)
00748 {
00749     return _pMaterialPal->getRecord(uiIdx);
00750 }
00751
00752 void OFHeaderRecord::dump(UInt32 uiIndent)
00753 {
00754     indentLog(uiIndent, PLOG);
00755     PLOG << "HeaderRecord" << std::endl;
00756
00757     indentLog(uiIndent, PLOG);
00758     PLOG << "{" << std::endl;
00759
00760     uiIndent += 2;
00761
00762     _pVertexPal  ->dump(uiIndent);
00763     _pTexturePal ->dump(uiIndent);
00764     _pMaterialPal->dump(uiIndent);
00765
00766     uiIndent -= 2;
00767
00768     indentLog(uiIndent, PLOG);
00769     PLOG << "}" << std::endl;
00770
00771     indentLog(uiIndent, PLOG);
00772     PLOG << "[" << std::endl;
00773
00774     uiIndent += 2;
00775
00776     for(UInt32 i = 0; i < _vChildren.size(); ++i)
00777     {
00778         _vChildren[i]->dump(uiIndent);
00779     }
00780
00781     uiIndent -= 2;
00782
00783     indentLog(uiIndent, PLOG);
00784     PLOG << "]" << std::endl;
00785 }
00786
00787
00788 //---------------------------------------------------------------------
00789 // OFUnknownRecord
00790 //---------------------------------------------------------------------
00791
00792 OFUnknownRecord::OFUnknownRecord(const OFRecordHeader &oHeader) :
00793      Inherited(oHeader        ),
00794     _sOpCode  (oHeader.sOpCode),
00795     _vChildren(               )
00796 {
00797 }
00798
00799 OFUnknownRecord::~OFUnknownRecord(void)
00800 {
00801 }
00802
00803 bool OFUnknownRecord::read(std::istream &is, OFDatabase &oDB)
00804 {
00805     static std::vector<char> tmpBuf;
00806
00807     if(_sLength > 4)
00808     {
00809         tmpBuf.resize(_sLength);
00810
00811         is.read(&(tmpBuf.front()), _sLength - 4);
00812     }
00813
00814     return is.good();
00815 }
00816
00817 bool OFUnknownRecord::addChild(OFRecord *pChild)
00818 {
00819     if(pChild == NULL)
00820         return false;
00821
00822     _vChildren.push_back(pChild);
00823
00824     return true;
00825 }
00826
00827 UInt16 OFUnknownRecord::getOpCode(void)
00828 {
00829     return _sOpCode;
00830 }
00831
00832 NodeTransitPtr OFUnknownRecord::convertToNode(OFDatabase &oDB)
00833 {
00834     NodeTransitPtr returnValue = makeCoredNode<Group>();
00835
00836     for(UInt32 i = 0; i < _vChildren.size(); ++i)
00837         returnValue->addChild(_vChildren[i]->convertToNode(oDB));
00838
00839     return returnValue;
00840 }
00841
00842 void OFUnknownRecord::dump(UInt32 uiIndent)
00843 {
00844     indentLog(uiIndent, PLOG);
00845     PLOG << "OFUnknownRecord - " << _sOpCode
00846          << " - "                << findDesc(_sOpCode)
00847          << std::endl;
00848 }
00849
00850 //---------------------------------------------------------------------
00851 // OFTexturePaletteRecord
00852 //---------------------------------------------------------------------
00853
00854 OFRecordTransitPtr OFTexturePaletteRecord::create(const OFRecordHeader &oHeader)
00855 {
00856     return OFRecordTransitPtr(new OFTexturePaletteRecord(oHeader));
00857 }
00858
00859 OFTexturePaletteRecord::OFTexturePaletteRecord(const OFRecordHeader &oHeader) :
00860     Inherited(oHeader),
00861     pTexObj()
00862 {
00863 }
00864
00865 OFTexturePaletteRecord::~OFTexturePaletteRecord(void)
00866 {
00867     pTexObj = NULL;
00868 }
00869
00870 bool OFTexturePaletteRecord::read(std::istream &is, OFDatabase &oDB)
00871 {
00872     Inherited::readChar8(is, szFilename, 200);
00873     Inherited::readVal  (is, iPatternIdx    );
00874     Inherited::readVal  (is, iPatternX      );
00875     Inherited::readVal  (is, iPatternY      );
00876
00877     ImageUnrecPtr pImage = ImageFileHandler::the()->read(szFilename);
00878
00879     if(pImage != NULL)
00880     {
00881         pTexObj = TextureObjChunk::create();
00882
00883         pTexObj->setImage(pImage);
00884     }
00885     else
00886     {
00887         std::string szTmp = szFilename;
00888
00889         std::string::size_type uiPos = szTmp.rfind('/');
00890
00891         if(uiPos != std::string::npos)
00892         {
00893             pImage = ImageFileHandler::the()->read(
00894                 &(szFilename[uiPos + 1]));
00895
00896             if(pImage != NULL)
00897             {
00898                 pTexObj = TextureObjChunk::create();
00899
00900                 pTexObj->setImage(pImage);
00901             }
00902             else
00903             {
00904                 FWARNING(("OFTexturePaletteRecord::read: Could not read image "
00905                           "[%s].\n", &(szFilename[uiPos + 1])));
00906             }
00907         }
00908         else
00909         {
00910             FWARNING(("OFTexturePaletteRecord::read: Could not read image "
00911                       "[%s].\n", szFilename));
00912         }
00913     }
00914
00915     return is.good();
00916 }
00917
00918 UInt16 OFTexturePaletteRecord::getOpCode(void)
00919 {
00920     return OpCode;
00921 }
00922
00923 void OFTexturePaletteRecord::dump(UInt32 uiIndent)
00924 {
00925     indentLog(uiIndent, PLOG);
00926     PLOG << "TexturePaletteRecord" << std::endl;
00927
00928     indentLog(uiIndent, PLOG);
00929     PLOG << "{" << std::endl;
00930
00931     uiIndent += 2;
00932
00933     indentLog(uiIndent, PLOG);
00934     PLOG << "Filename : " << szFilename << std::endl;
00935
00936     indentLog(uiIndent, PLOG);
00937     PLOG << "PatternIdx : " << iPatternIdx << std::endl;
00938
00939     indentLog(uiIndent, PLOG);
00940     PLOG << "PatternX : " << iPatternX << std::endl;
00941
00942     indentLog(uiIndent, PLOG);
00943     PLOG << "PatternY : " << iPatternY << std::endl;
00944
00945     uiIndent -= 2;
00946
00947     indentLog(uiIndent, PLOG);
00948     PLOG << "}" << std::endl;
00949 }
00950
00951 Int32 OFTexturePaletteRecord::getPatternIdx(void)
00952 {
00953     return iPatternIdx;
00954 }
00955
00956 TextureObjChunk *OFTexturePaletteRecord::getTexObj(void) const
00957 {
00958     return pTexObj;
00959 }
00960
00961 OFRecordFactoryBase::RegisterRecord OFTexturePaletteRecord::_regHelper(
00962     &OFTexturePaletteRecord::create,
00963     OFTexturePaletteRecord::OpCode);
00964
00965
00966 //---------------------------------------------------------------------
00967 // OFVertexPaletteRecord
00968 //---------------------------------------------------------------------
00969
00970 OFRecordTransitPtr OFVertexPaletteRecord::create(const OFRecordHeader &oHeader)
00971 {
00972     return OFRecordTransitPtr(new OFVertexPaletteRecord(oHeader));
00973 }
00974
00975 OFVertexPaletteRecord::OFVertexPaletteRecord(const OFRecordHeader &oHeader) :
00976     Inherited(oHeader)
00977 {
00978 }
00979
00980 OFVertexPaletteRecord::~OFVertexPaletteRecord(void)
00981 {
00982 }
00983
00984 bool OFVertexPaletteRecord::read(std::istream &is, OFDatabase &oDB)
00985 {
00986     static std::vector<char> tmpBuf;
00987
00988     Int32 iFullLength;
00989
00990     is.read(reinterpret_cast<char *>(&iFullLength), 4);
00991
00992     iFullLength = osgBigEndianToHost(iFullLength);
00993
00994     Int32          iRead = 0;
00995
00996     Real64         tmpDouble[3];
00997     OFRecordHeader oRHeader;
00998     bool           rc = true;
00999     Vec3f          tmpNorm;
01000     Vec2f          tmpTexCoord;
01001     VertexInfo     tmpInfo;
01002
01003     while(iRead < iFullLength - 8 && is.good() == true)
01004     {
01005         rc = oRHeader.read(is);
01006
01007         if(rc == false)
01008         {
01009             break;
01010         }
01011
01012         tmpInfo.uiType   = HasPos;
01013         tmpInfo.uiOffset = iRead + 8;
01014
01015         tmpInfo.uiIdx[ColIdx     ] = -1;
01016         tmpInfo.uiIdx[NormIdx    ] = -1;
01017         tmpInfo.uiIdx[TexCoordIdx] = -1;
01018
01019         Int32 uiSize = 0;
01020
01021         uiSize += Inherited::readVal(is, tmpInfo.uiColNameIdx);
01022         uiSize += Inherited::readVal(is, tmpInfo.iFlags      );
01023
01024         uiSize += Inherited::readVal(is, tmpDouble[0]);
01025         uiSize += Inherited::readVal(is, tmpDouble[1]);
01026         uiSize += Inherited::readVal(is, tmpDouble[2]);
01027
01028         tmpInfo.uiIdx[PosIdx] = vPositions.size();
01029
01030         vPositions.push_back(Pnt3f(tmpDouble[0], tmpDouble[1], tmpDouble[2]));
01031
01032         if(oRHeader.sOpCode == 69 || oRHeader.sOpCode == 70)
01033         {
01034             uiSize += Inherited::readVal(is, tmpNorm[0]);
01035             uiSize += Inherited::readVal(is, tmpNorm[1]);
01036             uiSize += Inherited::readVal(is, tmpNorm[2]);
01037
01038             tmpInfo.uiIdx[NormIdx]  = vNormals.size();
01039             tmpInfo.uiType         |= HasNorm;
01040
01041             vNormals.push_back(tmpNorm);
01042         }
01043
01044
01045         if(oRHeader.sOpCode == 70 || oRHeader.sOpCode == 71)
01046         {
01047             uiSize += Inherited::readVal(is, tmpTexCoord[0]);
01048             uiSize += Inherited::readVal(is, tmpTexCoord[1]);
01049
01050             tmpInfo.uiIdx[TexCoordIdx]  = vTexCoords.size();
01051             tmpInfo.uiType             |= HasTexCoord;
01052
01053             vTexCoords.push_back(tmpTexCoord);
01054         }
01055
01056
01057         uiSize += Inherited::readVal(is, tmpInfo.iPackedCol);
01058         uiSize += Inherited::readVal(is, tmpInfo.iColIdx   );
01059
01060         if(oRHeader.sOpCode == 69 || oRHeader.sOpCode == 70)
01061         {
01062             if(uiSize < oRHeader.sLength - 4)
01063             {
01064                 uiSize += Inherited::readVal(is, tmpInfo.iPad1);
01065             }
01066         }
01067
01068         vVertexInfo.push_back(tmpInfo);
01069
01070         iRead += oRHeader.sLength;
01071     }
01072
01073 #if 0
01074     fprintf(stderr, "Got %d vertices\n",
01075             vVertexInfo.size());
01076 #endif
01077 
01078     return is.good();
01079 }
01080
01081 UInt16 OFVertexPaletteRecord::getOpCode(void)
01082 {
01083     return OpCode;
01084 }
01085
01086 const OFVertexPaletteRecord::VertexInfo *
01087     OFVertexPaletteRecord::getVertexInfo(UInt32 uiOff) const
01088 {
01089     std::vector<VertexInfo>::const_iterator iLBound =
01090         std::lower_bound(vVertexInfo.begin(),
01091                          vVertexInfo.end  (),
01092                          uiOff);
01093
01094     if(iLBound != vVertexInfo.end())
01095     {
01096         return &(*iLBound);
01097     }
01098
01099     return NULL;
01100 }
01101
01102 const Pnt3f &OFVertexPaletteRecord::getPos(UInt32 uiIdx) const
01103 {
01104     OSG_ASSERT(uiIdx < vPositions.size());
01105
01106     return vPositions[uiIdx];
01107 }
01108
01109 const Vec3f &OFVertexPaletteRecord::getNormal(UInt32 uiIdx) const
01110 {
01111     OSG_ASSERT(uiIdx < vNormals.size());
01112
01113     return vNormals[uiIdx];
01114 }
01115
01116 const Vec2f &OFVertexPaletteRecord::getTexCoord(UInt32 uiIdx) const
01117 {
01118     OSG_ASSERT(uiIdx < vTexCoords.size());
01119
01120     return vTexCoords[uiIdx];
01121 }
01122
01123 bool OFVertexPaletteRecord::VertexInfo::operator <(const UInt32 uiOff) const
01124 {
01125     return this->uiOffset < uiOff;
01126 }
01127
01128 bool OFVertexPaletteRecord::VertexInfo::operator <(
01129     const VertexInfo &vInfo) const
01130 {
01131     return this->uiOffset < vInfo.uiOffset;
01132 }
01133
01134 bool operator <(const UInt32                             uiOff,
01135                 const OFVertexPaletteRecord::VertexInfo &vInfo)
01136 {
01137     return uiOff < vInfo.uiOffset;
01138 }
01139
01140 OFRecordFactoryBase::RegisterRecord OFVertexPaletteRecord::_regHelper(
01141     &OFVertexPaletteRecord::create,
01142     OFVertexPaletteRecord::OpCode);
01143
01144 //---------------------------------------------------------------------
01145 // OFMaterialPaletteRecord
01146 //---------------------------------------------------------------------
01147
01148 OFMaterialPaletteRecord::OFMaterialPaletteRecord(
01149     const OFRecordHeader &oHeader) :
01150
01151     Inherited (oHeader)
01152 {
01153     // nothing to do
01154 }
01155
01156 OFMaterialPaletteRecord::~OFMaterialPaletteRecord(void)
01157 {
01158     // nothing to do
01159 }
01160
01161 OFRecordTransitPtr OFMaterialPaletteRecord::create(
01162     const OFRecordHeader &oHeader)
01163 {
01164     return OFRecordTransitPtr(new OFMaterialPaletteRecord(oHeader));
01165 }
01166
01167 bool OFMaterialPaletteRecord::read(std::istream &is, OFDatabase &oDB)
01168 {
01169     Inherited::readVal  (is, iMaterialIdx      );
01170     Inherited::readChar8(is, szMaterialName, 12);
01171     Inherited::readVal  (is, iFlags            );
01172     Inherited::readVal  (is, colAmbient[0]     );
01173     Inherited::readVal  (is, colAmbient[1]     );
01174     Inherited::readVal  (is, colAmbient[2]     );
01175     Inherited::readVal  (is, colDiffuse[0]     );
01176     Inherited::readVal  (is, colDiffuse[1]     );
01177     Inherited::readVal  (is, colDiffuse[2]     );
01178     Inherited::readVal  (is, colSpecular[0]    );
01179     Inherited::readVal  (is, colSpecular[1]    );
01180     Inherited::readVal  (is, colSpecular[2]    );
01181     Inherited::readVal  (is, colEmissive[0]    );
01182     Inherited::readVal  (is, colEmissive[1]    );
01183     Inherited::readVal  (is, colEmissive[2]    );
01184     Inherited::readVal  (is, fShininess        );
01185     Inherited::readVal  (is, fAlpha            );
01186     Inherited::readVal  (is, iPad              );
01187
01188     return is.good();
01189 }
01190
01191 UInt16 OFMaterialPaletteRecord::getOpCode(void)
01192 {
01193     return OpCode;
01194 }
01195
01196 void OFMaterialPaletteRecord::dump(UInt32 uiIndent)
01197 {
01198     indentLog(uiIndent, PLOG);
01199     PLOG << "OFMaterialPaletteRecord : " << std::endl;
01200
01201     indentLog(uiIndent, PLOG);
01202     PLOG << "{" << std::endl;
01203
01204     uiIndent += 2;
01205
01206     indentLog(uiIndent, PLOG);
01207     PLOG << "MaterialIdx : " << iMaterialIdx << std::endl;
01208
01209     indentLog(uiIndent, PLOG);
01210     PLOG << "MaterialName : " << szMaterialName << std::endl;
01211
01212     indentLog(uiIndent, PLOG);
01213     PLOG << "ColAmbient : " << colAmbient << std::endl;
01214
01215     indentLog(uiIndent, PLOG);
01216     PLOG << "ColDiffuse : " << colDiffuse << std::endl;
01217
01218     indentLog(uiIndent, PLOG);
01219     PLOG << "ColSpecular : " << colSpecular << std::endl;
01220
01221     indentLog(uiIndent, PLOG);
01222     PLOG << "ColEmissive : " << colEmissive << std::endl;
01223
01224     indentLog(uiIndent, PLOG);
01225     PLOG << "Shininess : " << fShininess << std::endl;
01226
01227     indentLog(uiIndent, PLOG);
01228     PLOG << "Alpha : " << fAlpha << std::endl;
01229
01230     uiIndent -= 2;
01231
01232     indentLog(uiIndent, PLOG);
01233     PLOG << "}" << std::endl;
01234 }
01235
01236 Int32 OFMaterialPaletteRecord::getMaterialIdx(void)
01237 {
01238     return iMaterialIdx;
01239 }
01240
01241 const Color4f &OFMaterialPaletteRecord::getAmbient(void) const
01242 {
01243     return colAmbient;
01244 }
01245
01246 const Color4f &OFMaterialPaletteRecord::getDiffuse(void) const
01247 {
01248     return colDiffuse;
01249 }
01250
01251 const Color4f &OFMaterialPaletteRecord::getSpecular(void) const
01252 {
01253     return colSpecular;
01254 }
01255
01256 const Color4f &OFMaterialPaletteRecord::getEmissive(void) const
01257 {
01258     return colEmissive;
01259 }
01260
01261 Real32 OFMaterialPaletteRecord::getShininess(void) const
01262 {
01263     return fShininess;
01264 }
01265
01266 Real32 OFMaterialPaletteRecord::getAlpha(void) const
01267 {
01268     return fAlpha;
01269 }
01270
01271 OFRecordFactoryBase::RegisterRecord OFMaterialPaletteRecord::_regHelper(
01272     &OFMaterialPaletteRecord::create,
01273     OFMaterialPaletteRecord::OpCode);
01274
01275 //---------------------------------------------------------------------
01276 // OFMeshPrimitiveRecord
01277 //---------------------------------------------------------------------
01278
01279 OFMeshPrimitiveRecord::OFMeshPrimitiveRecord(const OFRecordHeader &oHeader) :
01280     Inherited    (oHeader),
01281     uiPrimType   (),
01282     uiIndexSize  (),
01283     uiVertexCount(),
01284     _vIndices    ()
01285 {
01286 }
01287
01288 OFMeshPrimitiveRecord::~OFMeshPrimitiveRecord(void)
01289 {
01290 }
01291
01292 OFRecordTransitPtr OFMeshPrimitiveRecord::create(
01293         const OFRecordHeader &oHeader)
01294 {
01295     return OFRecordTransitPtr(new OFMeshPrimitiveRecord(oHeader));
01296 }
01297
01298 bool OFMeshPrimitiveRecord::read(std::istream &is, OFDatabase &oDB)
01299 {
01300     Inherited::readVal(is, uiPrimType   );
01301     Inherited::readVal(is, uiIndexSize  );
01302     Inherited::readVal(is, uiVertexCount);
01303
01304     return readContinue(is, oDB, _sLength - 12);
01305 }
01306
01307 bool OFMeshPrimitiveRecord::readContinue(
01308     std::istream &is, OFDatabase &oDB, UInt16 uiLength)
01309 {
01310     switch(uiIndexSize)
01311     {
01312     case 1:
01313     {
01314         for(Int32 bytesLeft = uiLength; bytesLeft > 0; bytesLeft -= 1)
01315         {
01316             UInt8 tmpIdx;
01317             Inherited::readVal(is, tmpIdx);
01318
01319             _vIndices.push_back(tmpIdx);
01320         }
01321         break;
01322     }
01323
01324     case 2:
01325     {
01326         for(Int32 bytesLeft = uiLength; bytesLeft > 0; bytesLeft -= 2)
01327         {
01328             UInt16 tmpIdx;
01329             Inherited::readVal(is, tmpIdx);
01330
01331             _vIndices.push_back(tmpIdx);
01332         }
01333         break;
01334     }
01335
01336     case 4:
01337     {
01338         for(Int32 bytesLeft = uiLength; bytesLeft > 0; bytesLeft -= 4)
01339         {
01340             UInt32 tmpIdx;
01341             Inherited::readVal(is, tmpIdx);
01342
01343             _vIndices.push_back(tmpIdx);
01344         }
01345         break;
01346     }
01347
01348     default:
01349     {
01350         FWARNING(("OFMeshPrimitiveRecord::readContinue: IndexSize has "
01351                 "unrecognized value [%u].\n", uiIndexSize));
01352
01353         return Inherited::readContinue(is, oDB, uiLength);
01354     }
01355     }
01356
01357     return is.good();
01358 }
01359
01360 UInt16 OFMeshPrimitiveRecord::getOpCode(void)
01361 {
01362     return OpCode;
01363 }
01364
01365 void OFMeshPrimitiveRecord::dump(UInt32 uiIndent)
01366 {
01367     indentLog(uiIndent, PLOG);
01368     PLOG << "MeshPrimitiveRecord : " << std::endl;
01369
01370     indentLog(uiIndent, PLOG);
01371     PLOG << "{" << std::endl;
01372
01373     uiIndent += 2;
01374
01375     indentLog(uiIndent, PLOG);
01376     PLOG << "PrimType : " << uiPrimType << std::endl;
01377
01378     indentLog(uiIndent, PLOG);
01379     PLOG << "IndexSize : " << uiIndexSize << std::endl;
01380
01381     indentLog(uiIndent, PLOG);
01382     PLOG << "VertexCount : " << uiVertexCount << std::endl;
01383
01384     uiIndent -= 2;
01385
01386     indentLog(uiIndent, PLOG);
01387     PLOG << "}" << std::endl;
01388 }
01389
01390 OFMeshPrimitiveRecord::IndexStore &OFMeshPrimitiveRecord::editIndices(void)
01391 {
01392     return _vIndices;
01393 }
01394
01395 const OFMeshPrimitiveRecord::IndexStore &OFMeshPrimitiveRecord::getIndices(
01396     void) const
01397 {
01398     return _vIndices;
01399 }
01400
01401 OFRecordFactoryBase::RegisterRecord OFMeshPrimitiveRecord::_regHelper(
01402     &OFMeshPrimitiveRecord::create,
01403     OFMeshPrimitiveRecord::OpCode  );
01404
01405 //---------------------------------------------------------------------
01406 // OFLocalVertexPoolRecord
01407 //---------------------------------------------------------------------
01408
01409 OFLocalVertexPoolRecord::OFLocalVertexPoolRecord(
01410     const OFRecordHeader &oHeader) :
01411
01412     Inherited   (oHeader),
01413     _pPositions (NULL),
01414     _pColors    (NULL),
01415     _pNormals   (NULL),
01416     _texCoords  (),
01417     _vTriStrips (),
01418     _vTriFans   (),
01419     _vQuadStrips(),
01420     _vPolygons  ()
01421 {
01422     for(UInt32 i = 0; i < 8; ++i)
01423         _texCoords[i] = NULL;
01424 }
01425
01426 OFLocalVertexPoolRecord::~OFLocalVertexPoolRecord(void)
01427 {
01428 }
01429
01430 OFRecordTransitPtr OFLocalVertexPoolRecord::create(
01431         const OFRecordHeader &oHeader)
01432 {
01433     return OFRecordTransitPtr(new OFLocalVertexPoolRecord(oHeader));
01434 }
01435
01436 bool OFLocalVertexPoolRecord::read(std::istream &is, OFDatabase &oDB)
01437 {
01438     Inherited::readVal(is, uiNumVerts  );
01439     Inherited::readVal(is, uiAttribMask);
01440
01441     return readContinue(is, oDB, _sLength - 12);
01442 }
01443
01444 bool OFLocalVertexPoolRecord::readContinue(
01445     std::istream &is, OFDatabase &oDB, UInt16 uiLength)
01446 {
01447     if((uiAttribMask & AMHasColorIndex) != 0)
01448     {
01449         FWARNING(("OFLocalVertexPoolRecord::readContinue: "
01450                   "Color Index mode not supported.\n"));
01451     }
01452
01453     // make sure the needed properties exist
01454     if((uiAttribMask & AMHasPosition) != 0 && _pPositions == NULL)
01455         _pPositions = GeoPnt3dProperty::create();
01456
01457     if((uiAttribMask & AMHasColorValue) != 0 && _pColors == NULL)
01458         _pColors = GeoColor4ubProperty::create();
01459
01460     if((uiAttribMask & AMHasNormal) != 0 && _pNormals == NULL)
01461         _pNormals = GeoVec3fProperty::create();
01462
01463     for(UInt32 i = 0; i < 8; ++i)
01464     {
01465         if((uiAttribMask & AMHasTexCoords[i]) != 0 && _texCoords[i] == NULL)
01466             _texCoords[i] = GeoVec2fProperty::create();
01467     }
01468
01469     // read data
01470     for(Int32 bytesLeft = uiLength; bytesLeft > 0;)
01471     {
01472         if((uiAttribMask & AMHasPosition) != 0)
01473         {
01474             Pnt3d tmpPnt;
01475             Inherited::readVal(is, tmpPnt[0]);
01476             Inherited::readVal(is, tmpPnt[1]);
01477             Inherited::readVal(is, tmpPnt[2]);
01478
01479             _pPositions->push_back(tmpPnt);
01480
01481             bytesLeft -= 3 * 8;
01482         }
01483
01484         if((uiAttribMask & AMHasColorIndex) != 0)
01485         {
01486             UInt32 tmpVal;
01487             Inherited::readVal(is, tmpVal);
01488
01489             // TODO fetch the actual color from the palette
01490
01491             bytesLeft -= 4;
01492         }
01493
01494         if((uiAttribMask & AMHasColorValue) != 0)
01495         {
01496             Color4ub tmpVal;
01497             Inherited::readVal(is, tmpVal[3]);
01498             Inherited::readVal(is, tmpVal[0]);
01499             Inherited::readVal(is, tmpVal[1]);
01500             Inherited::readVal(is, tmpVal[2]);
01501
01502             _pColors->push_back(tmpVal);
01503
01504             bytesLeft -= 4;
01505         }
01506
01507         if((uiAttribMask & AMHasNormal) != 0)
01508         {
01509             Vec3f tmpVec;
01510             Inherited::readVal(is, tmpVec[0]);
01511             Inherited::readVal(is, tmpVec[1]);
01512             Inherited::readVal(is, tmpVec[2]);
01513
01514             tmpVec.normalize();
01515
01516             _pNormals->push_back(tmpVec);
01517
01518             bytesLeft -= 3 * 4;
01519         }
01520
01521         for(UInt32 i = 0; i < 8; ++i)
01522         {
01523             if((uiAttribMask & AMHasTexCoords[i]) != 0)
01524             {
01525                 Vec2f tmpVal;
01526                 Inherited::readVal(is, tmpVal[0]);
01527                 Inherited::readVal(is, tmpVal[1]);
01528
01529                 _texCoords[i]->push_back(tmpVal);
01530
01531                 bytesLeft -= 2 * 4;
01532             }
01533         }
01534     }
01535
01536     return is.good();
01537 }
01538
01539 bool OFLocalVertexPoolRecord::addChild(OFRecord *pChild)
01540 {
01541     if(pChild == NULL)
01542         return false;
01543
01544     bool rc = false;
01545
01546     switch(pChild->getOpCode())
01547     {
01548     case OFMeshPrimitiveRecord::OpCode:
01549     {
01550         OFMeshPrimitiveRecord *pPrim =
01551             dynamic_cast<OFMeshPrimitiveRecord *>(pChild);
01552
01553         rc = true;
01554
01555         switch(pPrim->uiPrimType)
01556         {
01557         case OFMeshPrimitiveRecord::PTTriStrip:
01558         {
01559             _vTriStrips.push_back(pPrim);
01560             break;
01561         }
01562
01563         case OFMeshPrimitiveRecord::PTTriFan:
01564         {
01565             _vTriFans.push_back(pPrim);
01566             break;
01567         }
01568
01569         case OFMeshPrimitiveRecord::PTQuadStrip:
01570         {
01571             _vQuadStrips.push_back(pPrim);
01572             break;
01573         }
01574
01575         case OFMeshPrimitiveRecord::PTPolygon:
01576         {
01577             _vPolygons.push_back(pPrim);
01578             break;
01579         }
01580
01581         default:
01582         {
01583             FWARNING(("OFMeshRecord::addChild: Unexpected primitive type [%u] "
01584                       "for MeshPrimitiveRecord.\n", pPrim->uiPrimType));
01585             rc =  Inherited::addChild(pChild);
01586             break;
01587         }
01588         }
01589         break;
01590     }
01591
01592     default:
01593     {
01594         FWARNING(("OFMeshRecord::addChild: Unexpected child type [%u - %s].\n",
01595                     pChild->getOpCode(), findDesc(pChild->getOpCode())));
01596         rc = Inherited::addChild(pChild);
01597         break;
01598     }
01599     }
01600
01601     return rc;
01602 }
01603
01604 UInt16 OFLocalVertexPoolRecord::getOpCode(void)
01605 {
01606     return OpCode;
01607 }
01608
01609 void OFLocalVertexPoolRecord::dump(UInt32 uiIndent)
01610 {
01611     indentLog(uiIndent, PLOG);
01612     PLOG << "LocalVertexPoolRecord : " << std::endl;
01613
01614     indentLog(uiIndent, PLOG);
01615     PLOG << "{" << std::endl;
01616
01617     uiIndent += 2;
01618
01619     indentLog(uiIndent, PLOG);
01620     PLOG << "NumVerts : " << uiNumVerts << std::endl;
01621
01622     PLOG.setf (std::ios::hex, std::ios::basefield);
01623
01624     indentLog(uiIndent, PLOG);
01625     PLOG << "FullAttribMask : " << uiAttribMask << std::endl;
01626
01627     PLOG.setf (std::ios::dec, std::ios::basefield);
01628
01629     indentLog(uiIndent, PLOG);
01630     PLOG << "AttribMask P:" << ((uiAttribMask & AMHasPosition    ) >> 31)
01631          <<          " Ci:" << ((uiAttribMask & AMHasColorIndex  ) >> 30)
01632          <<          " Cv:" << ((uiAttribMask & AMHasColorValue  ) >> 29)
01633          <<           " N:" << ((uiAttribMask & AMHasNormal      ) >> 28)
01634          <<         " UV0:" << ((uiAttribMask & AMHasTexCoords[0]) >> 27)
01635          <<         " UV1:" << ((uiAttribMask & AMHasTexCoords[1]) >> 26)
01636          <<         " UV2:" << ((uiAttribMask & AMHasTexCoords[2]) >> 25)
01637          <<         " UV3:" << ((uiAttribMask & AMHasTexCoords[3]) >> 24)
01638          <<         " UV4:" << ((uiAttribMask & AMHasTexCoords[4]) >> 23)
01639          <<         " UV5:" << ((uiAttribMask & AMHasTexCoords[5]) >> 22)
01640          <<         " UV6:" << ((uiAttribMask & AMHasTexCoords[6]) >> 21)
01641          <<         " UV7:" << ((uiAttribMask & AMHasTexCoords[7]) >> 20)
01642          << std::endl;
01643
01644     uiIndent -= 2;
01645
01646     indentLog(uiIndent, PLOG);
01647     PLOG << "}" << std::endl;
01648
01649     indentLog(uiIndent, PLOG);
01650     PLOG << "[" << std::endl;
01651
01652     uiIndent += 2;
01653
01654     for(UInt32 i = 0; i < _vTriStrips.size(); ++i)
01655         _vTriStrips[i]->dump(uiIndent);
01656
01657     for(UInt32 i = 0; i < _vTriFans.size(); ++i)
01658         _vTriFans[i]->dump(uiIndent);
01659
01660     for(UInt32 i = 0; i < _vQuadStrips.size(); ++i)
01661         _vQuadStrips[i]->dump(uiIndent);
01662
01663     for(UInt32 i = 0; i < _vPolygons.size(); ++i)
01664         _vPolygons[i]->dump(uiIndent);
01665
01666     uiIndent -= 2;
01667
01668     indentLog(uiIndent, PLOG);
01669     PLOG << "]" << std::endl;
01670 }
01671
01672 void OFLocalVertexPoolRecord::convertPrimitives(
01673         OFDatabase &oDB, Geometry *pGeo)
01674 {
01675     GeoUInt32PropertyUnrecPtr pInd = GeoUInt32Property::create();
01676
01677     for(UInt32 i = 0; i < _vTriStrips.size(); ++i)
01678     {
01679         pGeo->getTypes  ()->push_back(GL_TRIANGLE_STRIP            );
01680         pGeo->getLengths()->push_back(_vTriStrips[i]->uiVertexCount);
01681
01682         for(UInt32 j = 0; j < _vTriStrips[i]->_vIndices.size(); ++j)
01683         {
01684             pInd->push_back(_vTriStrips[i]->_vIndices[j]);
01685         }
01686     }
01687
01688     for(UInt32 i = 0; i < _vTriFans.size(); ++i)
01689     {
01690         pGeo->getTypes  ()->push_back(GL_TRIANGLE_FAN            );
01691         pGeo->getLengths()->push_back(_vTriFans[i]->uiVertexCount);
01692
01693         for(UInt32 j = 0; j < _vTriFans[i]->_vIndices.size(); ++j)
01694         {
01695             pInd->push_back(_vTriFans[i]->_vIndices[j]);
01696         }
01697     }
01698
01699     for(UInt32 i = 0; i < _vQuadStrips.size(); ++i)
01700     {
01701         pGeo->getTypes  ()->push_back(GL_QUAD_STRIP                 );
01702         pGeo->getLengths()->push_back(_vQuadStrips[i]->uiVertexCount);
01703
01704         for(UInt32 j = 0; j < _vQuadStrips[i]->_vIndices.size(); ++j)
01705         {
01706             pInd->push_back(_vQuadStrips[i]->_vIndices[j]);
01707         }
01708     }
01709
01710     for(UInt32 i = 0; i < _vPolygons.size(); ++i)
01711     {
01712         pGeo->getTypes  ()->push_back(GL_POLYGON                  );
01713         pGeo->getLengths()->push_back(_vPolygons[i]->uiVertexCount);
01714
01715         for(UInt32 j = 0; j < _vPolygons[i]->_vIndices.size(); ++j)
01716         {
01717             pInd->push_back(_vPolygons[i]->_vIndices[j]);
01718         }
01719     }
01720
01721     if((uiAttribMask & AMHasPosition) != 0)
01722     {
01723         pGeo->setProperty(_pPositions, Geometry::PositionsIndex);
01724         pGeo->setIndex   (pInd,        Geometry::PositionsIndex);
01725     }
01726
01727     if((uiAttribMask & AMHasColorIndex) != 0)
01728     {
01729         ; // TODO
01730     }
01731
01732     if((uiAttribMask & AMHasColorValue) != 0)
01733     {
01734         pGeo->setProperty(_pColors, Geometry::ColorsIndex);
01735         pGeo->setIndex   (pInd,     Geometry::ColorsIndex);
01736     }
01737
01738     if((uiAttribMask & AMHasNormal) != 0)
01739     {
01740         pGeo->setProperty(_pNormals, Geometry::NormalsIndex);
01741         pGeo->setIndex   (pInd,      Geometry::NormalsIndex);
01742     }
01743
01744     for(UInt32 i = 0; i < 8; ++i)
01745     {
01746         if((uiAttribMask & AMHasTexCoords[i]) != 0)
01747         {
01748             pGeo->setProperty(_texCoords[i], Geometry::TexCoordsIndex + i);
01749             pGeo->setIndex   (pInd,          Geometry::TexCoordsIndex + i);
01750         }
01751     }
01752 }
01753
01754 GeoPnt3dProperty *OFLocalVertexPoolRecord::getPositions(void) const
01755 {
01756     return _pPositions;
01757 }
01758
01759 GeoColor4ubProperty *OFLocalVertexPoolRecord::getColors(void) const
01760 {
01761     return _pColors;
01762 }
01763
01764 GeoVec3fProperty *OFLocalVertexPoolRecord::getNormals(void) const
01765 {
01766     return _pNormals;
01767 }
01768
01769 GeoVec2fProperty *OFLocalVertexPoolRecord::getTexCoords(UInt32 idx) const
01770 {
01771     return _texCoords[idx];
01772 }
01773
01774 OFRecordFactoryBase::RegisterRecord OFLocalVertexPoolRecord::_regHelper(
01775         &OFLocalVertexPoolRecord::create,
01776         OFLocalVertexPoolRecord::OpCode  );
01777
01778 const UInt32 OFLocalVertexPoolRecord::AMHasPosition     = 0x80000000;
01779 const UInt32 OFLocalVertexPoolRecord::AMHasColorIndex   = 0x40000000;
01780 const UInt32 OFLocalVertexPoolRecord::AMHasColorValue   = 0x20000000;
01781 const UInt32 OFLocalVertexPoolRecord::AMHasNormal       = 0x10000000;
01782 const UInt32 OFLocalVertexPoolRecord::AMHasTexCoords[8] =
01783 {
01784     0x08000000,
01785     0x04000000,
01786     0x02000000,
01787     0x01000000,
01788     0x00800000,
01789     0x00400000,
01790     0x00200000,
01791     0x00100000
01792 };
01793
01794 //---------------------------------------------------------------------
01795 // OFMeshRecord
01796 //---------------------------------------------------------------------
01797
01798 OFMeshRecord::OFMeshRecord(const OFRecordHeader &oHeader) :
01799         Inherited(oHeader)
01800 {
01801 }
01802
01803 OFMeshRecord::~OFMeshRecord(void)
01804 {
01805 }
01806
01807 OFRecordTransitPtr OFMeshRecord::create(const OFRecordHeader &oHeader)
01808 {
01809     return OFRecordTransitPtr(new OFMeshRecord(oHeader));
01810 }
01811
01812 bool OFMeshRecord::read(std::istream &is, OFDatabase &oDB)
01813 {
01814     Inherited::readChar8(is, szASCIIId, 8     );
01815     Inherited::readVal  (is, iPad1            );
01816     Inherited::readVal  (is, iIRColorCode     );
01817     Inherited::readVal  (is, iRelPrio         );
01818     Inherited::readVal  (is, iDrawType        );
01819     Inherited::readVal  (is, iTextureWhite    );
01820     Inherited::readVal  (is, uiColorNameIdx   );
01821     Inherited::readVal  (is, uiAltColorNameIdx);
01822     Inherited::readVal  (is, iPad2            );
01823     Inherited::readVal  (is, iTemplate        );
01824     Inherited::readVal  (is, iDetailTexIdx    );
01825     Inherited::readVal  (is, iTexIdx          );
01826     Inherited::readVal  (is, iMatIdx          );
01827     Inherited::readVal  (is, iSurfMatCode     );
01828     Inherited::readVal  (is, iFeatureId       );
01829     Inherited::readVal  (is, iIRMatCode       );
01830     Inherited::readVal  (is, uiTransparency   );
01831     Inherited::readVal  (is, uiLODGenControl  );
01832     Inherited::readVal  (is, uiLineStyle      );
01833     Inherited::readVal  (is, iFlags           );
01834     Inherited::readVal  (is, uiLightMode      );
01835     Inherited::readChar8(is, szPad3, 7        );
01836     Inherited::readVal  (is, uiPackedPrimCol  );
01837     Inherited::readVal  (is, uiPackedAltCol   );
01838     Inherited::readVal  (is, iTexMapIdx       );
01839     Inherited::readVal  (is, iPad4            );
01840     Inherited::readVal  (is, uiPrimColIdx     );
01841     Inherited::readVal  (is, uiAltColIdx      );
01842     Inherited::readVal  (is, iPad5            );
01843     Inherited::readVal  (is, iShaderIdx       );
01844
01845     return is.good();
01846 }
01847
01848 bool OFMeshRecord::addChild(OFRecord *pChild)
01849 {
01850     if(pChild == NULL)
01851         return false;
01852
01853     bool rc = false;
01854
01855     switch(pChild->getOpCode())
01856     {
01857     case OFLocalVertexPoolRecord::OpCode:
01858     {
01859         if(_pVertexPool != NULL)
01860             FWARNING(("OFMeshRecord::addChild: VertexPool already set.\n"));
01861
01862         _pVertexPool = dynamic_cast<OFLocalVertexPoolRecord *>(pChild);
01863         rc           = true;
01864         break;
01865     }
01866
01867     default:
01868     {
01869         FWARNING(("OFMeshRecord::addChild: Unexpected child type [%u - %s].\n",
01870                   pChild->getOpCode(), findDesc(pChild->getOpCode())));
01871         rc = Inherited::addChild(pChild);
01872         break;
01873     }
01874     }
01875
01876     return rc;
01877 }
01878
01879 UInt16 OFMeshRecord::getOpCode(void)
01880 {
01881     return OpCode;
01882 }
01883
01884 void OFMeshRecord::dump(UInt32 uiIndent)
01885 {
01886     indentLog(uiIndent, PLOG);
01887     PLOG << "MeshRecord : " << std::endl;
01888
01889     indentLog(uiIndent, PLOG);
01890     PLOG << "{" << std::endl;
01891
01892     uiIndent += 2;
01893
01894     indentLog(uiIndent, PLOG);
01895     PLOG << "ASCIIId : " << szASCIIId << std::endl;
01896
01897     indentLog(uiIndent, PLOG);
01898     PLOG << "TextureWhite : " << static_cast<UInt32>(iTextureWhite) << std::endl;
01899
01900     indentLog(uiIndent, PLOG);
01901     PLOG << "Template : " << static_cast<UInt32>(iTemplate) << std::endl;
01902
01903     indentLog(uiIndent, PLOG);
01904     PLOG << "Transparency : " << uiTransparency << std::endl;
01905
01906     indentLog(uiIndent, PLOG);
01907     PLOG << "DetailTexIdx : " << iDetailTexIdx << std::endl;
01908     indentLog(uiIndent, PLOG);
01909     PLOG << "TexIdx       : " << iTexIdx << std::endl;
01910     indentLog(uiIndent, PLOG);
01911     PLOG << "TexMapIdx    : " << iTexMapIdx << std::endl;
01912     indentLog(uiIndent, PLOG);
01913     PLOG << "MatIdx       : " << iMatIdx << std::endl;
01914
01915     PLOG.setf (std::ios::hex, std::ios::basefield);
01916
01917     indentLog(uiIndent, PLOG);
01918     PLOG << "FullFlags : " << iFlags << std::endl;
01919
01920     PLOG.setf (std::ios::dec, std::ios::basefield);
01921
01922     indentLog(uiIndent, PLOG);
01923     PLOG << "Flags : "
01924             << "(T : "   << ((iFlags & 0x80000000) >> 31) << ") "
01925             << "(NC : "  << ((iFlags & 0x40000000) >> 30) << ") "
01926             << "(NAC : " << ((iFlags & 0x20000000) >> 29) << ") "
01927             << "(PC  : " << ((iFlags & 0x10000000) >> 28) << ") "
01928             << std::endl;
01929
01930     indentLog(uiIndent, PLOG);
01931     PLOG << "LightMode    : " << UInt32(uiLightMode) << std::endl;
01932
01933     if(uiLightMode == 0 || uiLightMode == 2)
01934     {
01935         PLOG.setf (std::ios::hex, std::ios::basefield);
01936
01937         indentLog(uiIndent, PLOG);
01938         PLOG << "ColorPacked : " << uiPackedPrimCol << std::endl;
01939
01940         indentLog(uiIndent, PLOG);
01941         PLOG << "Color    : B : "
01942                 << (uiPackedPrimCol & 0x000000FF)
01943                 << " G : "
01944                 << ((uiPackedPrimCol & 0x0000FF00) >> 8)
01945                 << " R : "
01946                 << ((uiPackedPrimCol & 0x00FF0000) >> 16)
01947                 << std::endl;
01948
01949         PLOG.setf (std::ios::dec, std::ios::basefield);
01950
01951         indentLog(uiIndent, PLOG);
01952         PLOG << "ColorIdx    : " << uiPrimColIdx << std::endl;
01953     }
01954
01955     uiIndent -= 2;
01956
01957     indentLog(uiIndent, PLOG);
01958     PLOG << "}" << std::endl;
01959
01960     indentLog(uiIndent, PLOG);
01961     PLOG << "[" << std::endl;
01962
01963     uiIndent += 2;
01964
01965     if(_pVertexPool != NULL)
01966         _pVertexPool->dump(uiIndent);
01967
01968     uiIndent -= 2;
01969
01970     indentLog(uiIndent, PLOG);
01971     PLOG << "]" << std::endl;
01972 }
01973
01974 NodeTransitPtr OFMeshRecord::convertToNode(OFDatabase &oDB)
01975 {
01976     NodeTransitPtr returnValue(NULL);
01977
01978     if(_pVertexPool == NULL)
01979     {
01980         return returnValue;
01981     }
01982
01983                               returnValue = Node             ::create();
01984     GeometryUnrecPtr          pGeo        = Geometry         ::create();
01985     GeoUInt8PropertyUnrecPtr  pTypes      = GeoUInt8Property ::create();
01986     GeoUInt32PropertyUnrecPtr pLengths    = GeoUInt32Property::create();
01987
01988     pGeo->setTypes  (pTypes  );
01989     pGeo->setLengths(pLengths);
01990
01991     returnValue->setCore(pGeo);
01992
01993     _pVertexPool->convertPrimitives(oDB, pGeo);
01994
01995     ChunkMaterialUnrecPtr pChunkMat = ChunkMaterial::create();
01996
01997     if(iTextureWhite && iTexIdx != -1)
01998     {
01999         MaterialChunkUnrecPtr pMatChunk = MaterialChunk::create();
02000         Color4f               colDiffuse(1.f, 1.f, 1.f, 1.f);
02001
02002         pMatChunk->setDiffuse(colDiffuse);
02003
02004         pChunkMat->addChunk(pMatChunk);
02005     }
02006     else if(iMatIdx != -1)
02007     {
02008         const OFMaterialPaletteRecord *pMatRec   = oDB.getMatRecord(iMatIdx);
02009
02010         if(pMatRec != NULL)
02011         {
02012             MaterialChunkUnrecPtr      pMatChunk = MaterialChunk::create();
02013
02014             if((iFlags & FlagNoColor) != 0)
02015             {
02016                 // use material only
02017                 Color4f colMat;
02018
02019                 pMatChunk->setAmbient(pMatRec->getAmbient());
02020
02021                 colMat    = pMatRec->getDiffuse();
02022                 colMat[3] = pMatRec->getAlpha() * (1.f - (uiTransparency / 65535.f));
02023                 pMatChunk->setDiffuse(colMat);
02024
02025                 pMatChunk->setSpecular (pMatRec->getSpecular ());
02026                 pMatChunk->setShininess(pMatRec->getShininess());
02027                 pMatChunk->setEmission (pMatRec->getEmissive ());
02028
02029                 pChunkMat->addChunk(pMatChunk);
02030             }
02031             else if((iFlags & FlagPackedColor) != 0)
02032             {
02033                 // use uiPackedPrimCol and material
02034                 Color4f colGeo;
02035                 Color4f colMat;
02036
02037                 colGeo[0] = ((uiPackedPrimCol & 0x00FF0000) >> 16) / 255.f;
02038                 colGeo[1] = ((uiPackedPrimCol & 0x0000FF00) >>  8) / 255.f;
02039                 colGeo[2] = ((uiPackedPrimCol & 0x000000FF)      ) / 255.f;
02040                 colGeo[3] = 1.f;
02041
02042                 colMat    = pMatRec->getAmbient();
02043                 colMat[0] = colMat[0] * colGeo[0];
02044                 colMat[1] = colMat[1] * colGeo[1];
02045                 colMat[2] = colMat[2] * colGeo[2];
02046
02047                 pMatChunk->setAmbient(colMat);
02048
02049                 colMat    = pMatRec->getDiffuse();
02050                 colMat[0] = colMat[0] * colGeo[0];
02051                 colMat[1] = colMat[1] * colGeo[1];
02052                 colMat[2] = colMat[2] * colGeo[2];
02053                 colMat[3] = pMatRec->getAlpha() * (1.f - (uiTransparency / 65535.f));
02054
02055                 pMatChunk->setDiffuse  (colMat                 );
02056                 pMatChunk->setSpecular (pMatRec->getSpecular ());
02057                 pMatChunk->setShininess(pMatRec->getShininess());
02058                 pMatChunk->setEmission (pMatRec->getEmissive ());
02059
02060                 pChunkMat->addChunk(pMatChunk);
02061             }
02062             else
02063             {
02064                 // TODO: use uiPrimColIdx
02065             }
02066
02067             if(pMatChunk->isTransparent() &&
02068                pChunkMat->find(BlendChunk::getClassType()) == NULL)
02069             {
02070                 BlendChunkUnrecPtr pBlendChunk = BlendChunk::create();
02071
02072                 pBlendChunk->setSrcFactor (GL_SRC_ALPHA          );
02073                 pBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
02074
02075                 pChunkMat->addChunk(pBlendChunk);
02076             }
02077         }
02078     }
02079
02080     if(iTexIdx != -1)
02081     {
02082         const OFTexturePaletteRecord *pTexRec = oDB.getTexRecord(iTexIdx);
02083
02084         if(pTexRec != NULL)
02085         {
02086             TextureObjChunk *pTexObj = pTexRec->getTexObj();
02087
02088             if(pTexObj != NULL)
02089             {
02090                 pChunkMat->addChunk(pTexObj);
02091
02092                 if(pTexObj->getImage()->hasAlphaChannel() &&
02093                    pChunkMat->find(BlendChunk::getClassType()) == NULL)
02094                 {
02095                     BlendChunkUnrecPtr pBlendChunk = BlendChunk::create();
02096
02097                     pBlendChunk->setSrcFactor (GL_SRC_ALPHA          );
02098                     pBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
02099
02100                     pChunkMat->addChunk(pBlendChunk);
02101                 }
02102
02103                 TextureEnvChunkUnrecPtr pTexEnv = TextureEnvChunk::create();
02104
02105                 pTexEnv->setEnvMode(GL_MODULATE);
02106
02107                 pChunkMat->addChunk(pTexEnv);
02108             }
02109         }
02110         else
02111         {
02112             FFATAL(("OFMeshRecord::convertToNode: "
02113                     "No texture record for index [%d].\n", iTexIdx));
02114         }
02115     }
02116
02117     if(uiLightMode == LMMeshColor || uiLightMode == LMMeshColorLit)
02118     {
02119         MaterialChunk *pMatChunk = dynamic_cast<MaterialChunk *>(
02120             pChunkMat->find(MaterialChunk::getClassType()));
02121
02122         if(pMatChunk != NULL)
02123         {
02124             pMatChunk->setColorMaterial(GL_NONE);
02125
02126             if(uiLightMode == LMMeshColor)
02127                 pMatChunk->setLit(false);
02128         }
02129     }
02130
02131     if(uiLightMode == LMMeshColorLit || uiLightMode == LMVertexColorLit)
02132     {
02133         if(pGeo->getProperty(Geometry::NormalsIndex) == NULL)
02134             calcVertexNormals(pGeo);
02135     }
02136
02137     switch(iDrawType)
02138     {
02139     case DTSolidCullBack:
02140     {
02141         PolygonChunkUnrecPtr pPolyChunk = PolygonChunk::create();
02142         pPolyChunk->setCullFace(GL_BACK);
02143
02144         pChunkMat->addChunk(pPolyChunk);
02145         break;
02146     }
02147
02148     case DTSolid:
02149     {
02150         // nothing to do
02151         break;
02152     }
02153
02154     case DTWireframeClosed:
02155     case DTWireframe:
02156     {
02157         PolygonChunkUnrecPtr pPolyChunk = PolygonChunk::create();
02158         pPolyChunk->setFrontMode(GL_LINE);
02159         pPolyChunk->setBackMode (GL_LINE);
02160
02161         pChunkMat->addChunk(pPolyChunk);
02162         break;
02163     }
02164
02165     default:
02166     {
02167         FWARNING(("OFMeshRecord::convertToNode: Unhandled draw "
02168                   "type [%d].\n", iDrawType));
02169         break;
02170     }
02171     }
02172
02173
02174     pGeo->setMaterial(pChunkMat);
02175
02176     return returnValue;
02177 }
02178
02179 OFRecordFactoryBase::RegisterRecord OFMeshRecord::_regHelper(
02180     &OFMeshRecord::create,
02181      OFMeshRecord::OpCode  );
02182
02183 //---------------------------------------------------------------------
02184 // OFFaceRecord
02185 //---------------------------------------------------------------------
02186
02187 OFRecordTransitPtr OFFaceRecord::create(const OFRecordHeader &oHeader)
02188 {
02189     return OFRecordTransitPtr(new OFFaceRecord(oHeader));
02190 }
02191
02192 OFFaceRecord::OFFaceRecord(const OFRecordHeader &oHeader) :
02193      Inherited(oHeader),
02194     _pVList   (NULL   )
02195 {
02196 }
02197
02198 OFFaceRecord::~OFFaceRecord(void)
02199 {
02200     _pVList = NULL;
02201 }
02202
02203 bool OFFaceRecord::read(std::istream &is, OFDatabase &oDB)
02204 {
02205     Inherited::readChar8(is, szASCIIId, 8     );
02206     Inherited::readVal  (is, iIRColorCode     );
02207     Inherited::readVal  (is, iRelPrio         );
02208     Inherited::readVal  (is, iDrawType        );
02209     Inherited::readVal  (is, iTextureWhite    );
02210     Inherited::readVal  (is, uiColorNameIdx   );
02211     Inherited::readVal  (is, uiAltColorNameIdx);
02212     Inherited::readVal  (is, iPad1            );
02213     Inherited::readVal  (is, iTemplate        );
02214     Inherited::readVal  (is, iDetailTexIdx    );
02215     Inherited::readVal  (is, iTexIdx          );
02216     Inherited::readVal  (is, iMatIdx          );
02217     Inherited::readVal  (is, iSurfMatCode     );
02218     Inherited::readVal  (is, iFeatureId       );
02219     Inherited::readVal  (is, iIRMatCode       );
02220     Inherited::readVal  (is, uiTransparency   );
02221     Inherited::readVal  (is, uiLODGenControl  );
02222     Inherited::readVal  (is, uiLineStyle      );
02223     Inherited::readVal  (is, iFlags           );
02224     Inherited::readVal  (is, uiLightMode      );
02225     Inherited::readChar8(is, szPad2, 7        );
02226     Inherited::readVal  (is, uiPackedPrimCol  );
02227     Inherited::readVal  (is, uiPackedAltCol   );
02228     Inherited::readVal  (is, iTexMapIdx       );
02229     Inherited::readVal  (is, iPad3            );
02230     Inherited::readVal  (is, uiPrimColIdx     );
02231     Inherited::readVal  (is, uiAltColIdx      );
02232     Inherited::readVal  (is, iPad4            );
02233     Inherited::readVal  (is, iShaderIdx       );
02234
02235     return is.good();
02236 }
02237
02238 bool OFFaceRecord::addChild (OFRecord *pChild)
02239 {
02240     if(pChild == NULL)
02241     {
02242         return false;
02243     }
02244
02245     switch(pChild->getOpCode())
02246     {
02247         case OFVertexListRecord::OpCode:
02248         {
02249             if(_pVList != NULL)
02250             {
02251                 FWARNING(("OFFaceRecord::addChild: Vertex List already set.\n"));
02252             }
02253             else
02254             {
02255                 _pVList = dynamic_cast<OFVertexListRecord *>(pChild);
02256             }
02257
02258             break;
02259         }
02260
02261
02262         default:
02263         {
02264             FWARNING(("OFFaceRecord::addChild: Unknown child record "
02265                       "[%hu].\n", pChild->getOpCode()));
02266         }
02267     }
02268
02269     return true;
02270 }
02271
02272 UInt16 OFFaceRecord::getOpCode(void)
02273 {
02274     return OpCode;
02275 }
02276
02277 OFVertexListRecord *OFFaceRecord::getVertexList(void)
02278 {
02279     return _pVList;
02280 }
02281
02282 void OFFaceRecord::dump(UInt32 uiIndent)
02283 {
02284     indentLog(uiIndent, PLOG);
02285     PLOG << "FaceRecord : " << std::endl;
02286
02287     indentLog(uiIndent, PLOG);
02288     PLOG << "{" << std::endl;
02289
02290     uiIndent += 2;
02291
02292     indentLog(uiIndent, PLOG);
02293     PLOG << "TextureWhite : " << UInt32(iTextureWhite) << std::endl;
02294
02295     indentLog(uiIndent, PLOG);
02296     PLOG << "TexIdx       : " << iTexIdx << std::endl;
02297     indentLog(uiIndent, PLOG);
02298     PLOG << "TexMapIdx    : " << iTexMapIdx << std::endl;
02299     indentLog(uiIndent, PLOG);
02300     PLOG << "MatIdx       : " << iMatIdx << std::endl;
02301     indentLog(uiIndent, PLOG);
02302     PLOG << "Transparency : " << uiTransparency << std::endl;
02303
02304     PLOG.setf (std::ios::hex, std::ios::basefield);
02305
02306     indentLog(uiIndent, PLOG);
02307     PLOG << "FullFlags : " << iFlags << std::endl;
02308
02309     PLOG.setf (std::ios::dec, std::ios::basefield);
02310
02311     indentLog(uiIndent, PLOG);
02312     PLOG << "Flags : "
02313          << "(T : "   << ((iFlags & 0x80000000) >> 31) << ") "
02314          << "(NC : "  << ((iFlags & 0x40000000) >> 30) << ") "
02315          << "(NAC : " << ((iFlags & 0x20000000) >> 29) << ") "
02316          << "(PC  : " << ((iFlags & 0x10000000) >> 28) << ") "
02317          << std::endl;
02318
02319     indentLog(uiIndent, PLOG);
02320     PLOG << "LightMode    : " << UInt32(uiLightMode) << std::endl;
02321
02322     if(uiLightMode == 0 || uiLightMode == 2)
02323     {
02324         PLOG.setf (std::ios::hex, std::ios::basefield);
02325
02326         indentLog(uiIndent, PLOG);
02327         PLOG << "ColorPacked : " << uiPackedPrimCol << std::endl;
02328
02329         indentLog(uiIndent, PLOG);
02330         PLOG << "Color    : B : "
02331              << (uiPackedPrimCol & 0x000000FF)
02332              << " G : "
02333              << ((uiPackedPrimCol & 0x0000FF00) >> 8)
02334              << " R : "
02335              << ((uiPackedPrimCol & 0x00FF0000) >> 16)
02336              << std::endl;
02337
02338         PLOG.setf (std::ios::dec, std::ios::basefield);
02339
02340         indentLog(uiIndent, PLOG);
02341         PLOG << "ColorIdx    : " << uiPrimColIdx << std::endl;
02342     }
02343
02344     uiIndent -= 2;
02345
02346     indentLog(uiIndent, PLOG);
02347     PLOG << "}" << std::endl;
02348 }
02349
02350 bool OFFaceRecord::operator ==(const OFFaceRecord &rhs) const
02351 {
02352     bool returnValue = (iDrawType     == rhs.iDrawType     &&
02353                         iTextureWhite == rhs.iTextureWhite &&
02354                         iTexIdx       == rhs.iTexIdx       &&
02355                         iMatIdx       == rhs.iMatIdx       &&
02356                         uiLightMode   == rhs.uiLightMode     );
02357
02358     if(uiLightMode == 0 || uiLightMode == 2)
02359     {
02360         returnValue &= (uiPackedPrimCol == rhs.uiPackedPrimCol);
02361     }
02362
02363     return returnValue;
02364 }
02365
02366 Int8 OFFaceRecord::getDrawType(void) const
02367 {
02368     return iDrawType;
02369 }
02370
02371 Int8 OFFaceRecord::getTextureWhite(void) const
02372 {
02373     return iTextureWhite;
02374 }
02375
02376 Int16 OFFaceRecord::getTexIdx(void) const
02377 {
02378     return iTexIdx;
02379 }
02380
02381 Int16 OFFaceRecord::getMatIdx(void) const
02382 {
02383     return iMatIdx;
02384 }
02385
02386 UInt16 OFFaceRecord::getTransparency(void) const
02387 {
02388     return uiTransparency;
02389 }
02390
02391 Int32 OFFaceRecord::getFlags(void) const
02392 {
02393     return iFlags;
02394 }
02395
02396 UInt8 OFFaceRecord::getLightMode(void) const
02397 {
02398     return uiLightMode;
02399 }
02400
02401 Color4f OFFaceRecord::getPrimColor(void) const
02402 {
02403     Color4f returnValue;
02404
02405     if((iFlags & FlagPackedColor) != 0)
02406     {
02407         returnValue[0] = ((uiPackedPrimCol & 0x00FF0000) >> 16) / 255.f;
02408         returnValue[1] = ((uiPackedPrimCol & 0x0000FF00) >>  8) / 255.f;
02409         returnValue[2] = ((uiPackedPrimCol & 0x000000FF)      ) / 255.f;
02410         returnValue[3] = 1.f;
02411     }
02412     else if((iFlags & FlagNoColor) == 0)
02413     {
02414         // TODO lookup color in index
02415     }
02416
02417     return returnValue;
02418 }
02419
02420 Color4f OFFaceRecord::getAltColor(void) const
02421 {
02422     Color4f returnValue;
02423
02424     if((iFlags & FlagPackedColor) != 0)
02425     {
02426         returnValue[0] = ((uiPackedAltCol & 0x00FF0000) >> 16) / 255.f;
02427         returnValue[1] = ((uiPackedAltCol & 0x0000FF00) >>  8) / 255.f;
02428         returnValue[2] = ((uiPackedAltCol & 0x000000FF)      ) / 255.f;
02429         returnValue[3] = 1.f;
02430     }
02431     else if((iFlags & FlagNoColor) == 0)
02432     {
02433         // TODO lookup color in index
02434     }
02435
02436     return returnValue;
02437 }
02438
02439 OFRecordFactoryBase::RegisterRecord OFFaceRecord::_regHelper(
02440     &OFFaceRecord::create,
02441     OFFaceRecord::OpCode);
02442
02443
02444 //---------------------------------------------------------------------
02445 // OFVertexListRecord
02446 //---------------------------------------------------------------------
02447
02448
02449 OFRecordTransitPtr OFVertexListRecord::create(const OFRecordHeader &oHeader)
02450 {
02451     return OFRecordTransitPtr(new OFVertexListRecord(oHeader));
02452 }
02453
02454 OFVertexListRecord::OFVertexListRecord(const OFRecordHeader &oHeader) :
02455     Inherited(oHeader)
02456 {
02457 }
02458
02459 OFVertexListRecord::~OFVertexListRecord(void)
02460 {
02461 }
02462
02463 bool OFVertexListRecord::read(std::istream &is, OFDatabase &oDB)
02464 {
02465     UInt32 uiListSize = (_sLength - 4) / 4;
02466
02467     _vIndices.resize(uiListSize);
02468
02469     for(UInt32 i = 0; i < uiListSize; ++i)
02470     {
02471         Inherited::readVal(is, _vIndices[i]);
02472     }
02473
02474     return is.good();
02475 }
02476
02477 UInt16 OFVertexListRecord::getOpCode(void)
02478 {
02479     return OpCode;
02480 }
02481
02482 const std::vector<Int32> &OFVertexListRecord::getIndices(void)
02483 {
02484     return _vIndices;
02485 }
02486
02487 OFRecordFactoryBase::RegisterRecord OFVertexListRecord::_regHelper(
02488     &OFVertexListRecord::create,
02489     OFVertexListRecord::OpCode);
02490
02491 //---------------------------------------------------------------------
02492 // OFGeometryContainerRecord
02493 //---------------------------------------------------------------------
02494
02495 OFGeometryContainer::OFGeometryContainer(const OFRecordHeader &oHeader) :
02496      Inherited   (oHeader),
02497     _vFaces      (       ),
02498     _vMeshes     (       )
02499 {
02500 }
02501
02502 OFGeometryContainer::~OFGeometryContainer(void)
02503 {
02504     for(UInt32 i = 0; i < _vFaces.size(); ++i)
02505     {
02506         _vFaces[i] = NULL;
02507     }
02508
02509     _vFaces.clear();
02510 }
02511
02512 bool OFGeometryContainer::addChild(OFRecord *pChild)
02513 {
02514     if(pChild == NULL)
02515     {
02516         return false;
02517     }
02518
02519     bool returnValue = false;
02520
02521     switch(pChild->getOpCode())
02522     {
02523     case OFFaceRecord::OpCode:
02524     {
02525         _vFaces.push_back(dynamic_cast<OFFaceRecord *>(pChild));
02526
02527         returnValue = true;
02528
02529         break;
02530     }
02531
02532     case OFMeshRecord::OpCode:
02533     {
02534         _vMeshes.push_back(dynamic_cast<OFMeshRecord *>(pChild));
02535
02536         returnValue = true;
02537         break;
02538     }
02539
02540     case OFLocalVertexPoolRecord::OpCode:
02541     {
02542         _vMeshes.back()->addChild(pChild);
02543
02544         returnValue = true;
02545         break;
02546     }
02547
02548     default:
02549     {
02550         break;
02551     }
02552     }
02553
02554     return returnValue;
02555 }
02556
02557 void OFGeometryContainer::groupFaces(
02558     std::vector< std::vector<OFFaceRecord *> > &vFaceGroups)
02559 {
02560     if(_vFaces.size() == 0)
02561         return;
02562
02563     vFaceGroups.clear();
02564
02565     std::vector<OFFaceRecord *> tmpVec;
02566     tmpVec.push_back(_vFaces[0]);
02567
02568     vFaceGroups.push_back(tmpVec);
02569
02570     UInt32 j = 0;
02571
02572     for(UInt32 i = 1; i < _vFaces.size(); ++i)
02573     {
02574         for(j = 0; j < vFaceGroups.size(); ++j)
02575         {
02576             if(*(_vFaces[i]) == *(vFaceGroups[j][0]))
02577             {
02578                 vFaceGroups[j].push_back(_vFaces[i]);
02579                 break;
02580             }
02581         }
02582
02583         if(j == vFaceGroups.size())
02584         {
02585             tmpVec.clear();
02586             tmpVec.push_back(_vFaces[i]);
02587
02588             vFaceGroups.push_back(tmpVec);
02589         }
02590     }
02591 }
02592
02593 NodeTransitPtr OFGeometryContainer::convertFaceGroup(
02594     std::vector<OFFaceRecord *> &vFaceGroup,
02595     OFDatabase                  &oDB)
02596 {
02597     NodeTransitPtr returnValue(NULL);
02598
02599     if(vFaceGroup.size() == 0)
02600         return returnValue;
02601
02602     typedef OFVertexPaletteRecord::VertexInfo VertexInfo;
02603
02604                      returnValue = Node    ::create();
02605     GeometryUnrecPtr pGeo        = Geometry::create();
02606
02607     returnValue->setCore(pGeo);
02608
02609     GeoUInt32PropertyUnrecPtr  pindex = GeoUInt32Property::create();
02610     GeoUInt32PropertyUnrecPtr  nindex = NULL;
02611     GeoUInt32PropertyUnrecPtr  tindex = NULL;
02612     GeoUInt32PropertyUnrecPtr  lens   = GeoUInt32Property::create();
02613     GeoUInt8PropertyUnrecPtr   types  = GeoUInt8Property ::create();
02614
02615     GeoUInt32Property::StoredFieldType *pPI = pindex->editFieldPtr();
02616     GeoUInt32Property::StoredFieldType *pNI = NULL;
02617     GeoUInt32Property::StoredFieldType *pTI = NULL;
02618     GeoUInt32Property::StoredFieldType *pL  = lens ->editFieldPtr();
02619     GeoUInt8Property ::StoredFieldType *pT  = types->editFieldPtr();
02620
02621     const OFVertexPaletteRecord *pVertexPal = oDB.getVertexPalette();
02622
02623     UInt32 uiNumValid;
02624
02625     GeoPnt3fPropertyUnrecPtr  pnts  = GeoPnt3fProperty ::create();
02626     GeoVec3fPropertyUnrecPtr  norms = NULL;
02627     GeoVec2fPropertyUnrecPtr  tex   = NULL;
02628
02629     GeoPnt3fProperty::StoredFieldType *pPos  = pnts ->editFieldPtr();
02630     GeoVec3fProperty::StoredFieldType *pNorm = NULL;
02631     GeoVec2fProperty::StoredFieldType *pTX   = NULL;
02632
02633     UInt16 uiVertexType = 0;
02634     bool   bSingleIdx   = true;
02635
02636     for(UInt32 i = 0; i < vFaceGroup.size(); ++i)
02637     {
02638         OFVertexListRecord *pVList = vFaceGroup[i]->getVertexList();
02639
02640         if(pVList != NULL)
02641         {
02642             const std::vector<Int32> &vIndices = pVList->getIndices();
02643
02644             uiNumValid = 0;
02645
02646             for(UInt32 j = 0; j < vIndices.size(); ++j)
02647             {
02648                 const VertexInfo *vInfo =
02649                     pVertexPal->getVertexInfo(vIndices[j]);
02650
02651                 if(vInfo != NULL)
02652                 {
02653                     // First Vertex
02654                     if(i == 0 && j == 0)
02655                     {
02656                         uiVertexType = vInfo->uiType;
02657
02658                         if(uiVertexType & OFVertexPaletteRecord::HasNorm)
02659                         {
02660                             norms  = GeoVec3fProperty ::create();
02661                             pNorm  = norms->editFieldPtr();
02662
02663                             nindex = GeoUInt32Property::create();
02664                             pNI    = nindex->editFieldPtr();
02665                         }
02666
02667                         if(uiVertexType & OFVertexPaletteRecord::HasTexCoord)
02668                         {
02669                             tex    = GeoVec2fProperty ::create();
02670                             pTX    = tex ->editFieldPtr();
02671
02672                             tindex = GeoUInt32Property::create();
02673                             pTI    = tindex->editFieldPtr();
02674                        }
02675                     }
02676
02677                     if(uiVertexType != vInfo->uiType)
02678                     {
02679                         FWARNING(("OFGeometryContainer::convertFaceGroup: "
02680                                   "Found different vtypes\n"));
02681                         break;
02682                     }
02683
02684                     UInt32 uiPosIdx =
02685                         vInfo->uiIdx[OFVertexPaletteRecord::PosIdx];
02686
02687                     pPI->push_back(pPos->size());
02688
02689                     pPos->push_back(pVertexPal->getPos(uiPosIdx));
02690
02691                     if(uiVertexType & OFVertexPaletteRecord::HasNorm)
02692                     {
02693                         UInt32 uiNormIdx =
02694                             vInfo->uiIdx[OFVertexPaletteRecord::NormIdx];
02695
02696                         pNI->push_back(pNorm->size());
02697
02698                         pNorm->push_back(pVertexPal->getNormal(uiNormIdx));
02699
02700                         if(uiNormIdx != uiPosIdx)
02701                         {
02702                             bSingleIdx = false;
02703                         }
02704                     }
02705
02706                     if(uiVertexType & OFVertexPaletteRecord::HasTexCoord)
02707                     {
02708                         UInt32 uiTXIdx =
02709                             vInfo->uiIdx[OFVertexPaletteRecord::TexCoordIdx];
02710
02711                         pTI->push_back(pTX->size());
02712
02713                         pTX->push_back(pVertexPal->getTexCoord(uiTXIdx));
02714
02715                         if(uiTXIdx != uiPosIdx)
02716                         {
02717                             bSingleIdx = false;
02718                         }
02719                     }
02720
02721                     ++uiNumValid;
02722                 }
02723             }
02724
02725             pL->push_back(uiNumValid);
02726             pT->push_back(GL_POLYGON);
02727         }
02728     }
02729
02730     pGeo->setIndex   (pindex, Geometry::PositionsIndex);
02731     pGeo->setProperty(pnts,   Geometry::PositionsIndex);
02732
02733     if(norms != NULL)
02734     {
02735         if(bSingleIdx == true)
02736         {
02737             pGeo->setIndex(pindex, Geometry::NormalsIndex);
02738         }
02739         else
02740         {
02741             pGeo->setIndex(nindex, Geometry::NormalsIndex);
02742         }
02743
02744         pGeo->setProperty(norms, Geometry::NormalsIndex);
02745     }
02746
02747     if(tex != NULL)
02748     {
02749         if(bSingleIdx == true)
02750         {
02751             pGeo->setIndex(pindex, Geometry::TexCoordsIndex);
02752         }
02753         else
02754         {
02755             pGeo->setIndex(tindex, Geometry::TexCoordsIndex);
02756         }
02757
02758         pGeo->setProperty(tex, Geometry::TexCoordsIndex);
02759     }
02760
02761     pGeo->setTypes   (types                           );
02762     pGeo->setLengths (lens                            );
02763
02764     ChunkMaterialUnrecPtr pChunkMat = ChunkMaterial::create();
02765
02766     if(vFaceGroup[0]->getTextureWhite() &&
02767        vFaceGroup[0]->getTexIdx      () != -1)
02768     {
02769         MaterialChunkUnrecPtr pMatChunk = MaterialChunk::create();
02770         Color4f               colDiffuse(1.f, 1.f, 1.f, 1.f);
02771
02772         pMatChunk->setDiffuse(colDiffuse);
02773
02774         pChunkMat->addChunk(pMatChunk);
02775     }
02776     else if(vFaceGroup[0]->getMatIdx() != -1)
02777     {
02778         const OFMaterialPaletteRecord *pMatRec   =
02779             oDB.getMatRecord(vFaceGroup[0]->getMatIdx());
02780
02781         if(pMatRec != NULL)
02782         {
02783             MaterialChunkUnrecPtr      pMatChunk = MaterialChunk::create();
02784
02785             if((vFaceGroup[0]->getFlags() & FlagNoColor) != 0)
02786             {
02787                 // use material only
02788                 Color4f colMat;
02789
02790                 pMatChunk->setAmbient(pMatRec->getAmbient());
02791
02792                 colMat    = pMatRec->getDiffuse();
02793                 colMat[3] = pMatRec->getAlpha() * (1.f - (vFaceGroup[0]->getTransparency() / 65535.f));
02794                 pMatChunk->setDiffuse(colMat);
02795
02796                 pMatChunk->setSpecular (pMatRec->getSpecular ());
02797                 pMatChunk->setShininess(pMatRec->getShininess());
02798                 pMatChunk->setEmission (pMatRec->getEmissive ());
02799
02800                 pChunkMat->addChunk(pMatChunk);
02801             }
02802             else if((vFaceGroup[0]->getFlags() & FlagPackedColor) != 0)
02803             {
02804                 // use uiPackedPrimCol and material
02805                 Color4f colGeo;
02806                 Color4f colMat;
02807
02808                 colGeo    = vFaceGroup[0]->getPrimColor();
02809
02810                 colMat    = pMatRec->getAmbient();
02811                 colMat[0] = colMat[0] * colGeo[0];
02812                 colMat[1] = colMat[1] * colGeo[1];
02813                 colMat[2] = colMat[2] * colGeo[2];
02814
02815                 pMatChunk->setAmbient(colMat);
02816
02817                 colMat    = pMatRec->getDiffuse();
02818                 colMat[0] = colMat[0] * colGeo[0];
02819                 colMat[1] = colMat[1] * colGeo[1];
02820                 colMat[2] = colMat[2] * colGeo[2];
02821                 colMat[3] = pMatRec->getAlpha() * (1.f - (vFaceGroup[0]->getTransparency() / 65535.f));
02822
02823                 SLOG << "OFGeometryContainer::convertFaceGroup: "
02824                         << "PC pMatRec->getAlpha() [" << pMatRec->getAlpha()
02825                         << "] Transparency [" << vFaceGroup[0]->getTransparency()
02826                         << "] colMat[3] [" << colMat[3] << "]" << std::endl;
02827
02828                 pMatChunk->setDiffuse  (colMat                 );
02829                 pMatChunk->setSpecular (pMatRec->getSpecular ());
02830                 pMatChunk->setShininess(pMatRec->getShininess());
02831                 pMatChunk->setEmission (pMatRec->getEmissive ());
02832
02833                 pChunkMat->addChunk(pMatChunk);
02834             }
02835             else
02836             {
02837                 // TODO: use uiPrimColIdx
02838             }
02839
02840             if(pMatChunk->isTransparent() &&
02841                pChunkMat->find(BlendChunk::getClassType()) == NULL)
02842             {
02843                 BlendChunkUnrecPtr pBlendChunk = BlendChunk::create();
02844
02845                 pBlendChunk->setSrcFactor (GL_SRC_ALPHA          );
02846                 pBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
02847
02848                 pChunkMat->addChunk(pBlendChunk);
02849             }
02850         }
02851     }
02852
02853     if(vFaceGroup[0]->getTexIdx() != -1)
02854     {
02855         const OFTexturePaletteRecord *pTexRec =
02856             oDB.getTexRecord(vFaceGroup[0]->getTexIdx());
02857
02858         if(pTexRec != NULL)
02859         {
02860             TextureObjChunk *pTexObj = pTexRec->getTexObj();
02861
02862             if(pTexObj != NULL)
02863             {
02864                 pChunkMat->addChunk(pTexObj);
02865
02866                 if(pTexObj->getImage()->hasAlphaChannel() &&
02867                    pChunkMat->find(BlendChunk::getClassType()) == NULL)
02868                 {
02869                     BlendChunkUnrecPtr pBlendChunk = BlendChunk::create();
02870
02871                     pBlendChunk->setSrcFactor (GL_SRC_ALPHA          );
02872                     pBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
02873
02874                     pChunkMat->addChunk(pBlendChunk);
02875                 }
02876             }
02877         }
02878         else
02879         {
02880             FFATAL(("OFGeometryContainer::convertFaceGroup: "
02881                     "No texture record for index [%d].\n", vFaceGroup[0]->getTexIdx()));
02882         }
02883     }
02884
02885     if(vFaceGroup[0]->getLightMode() == LMMeshColor ||
02886        vFaceGroup[0]->getLightMode() == LMMeshColorLit )
02887     {
02888         MaterialChunk *pMatChunk = dynamic_cast<MaterialChunk *>(
02889             pChunkMat->find(MaterialChunk::getClassType()));
02890
02891         if(pMatChunk != NULL)
02892         {
02893             pMatChunk->setColorMaterial(GL_NONE);
02894
02895             if(vFaceGroup[0]->getLightMode() == LMMeshColor)
02896                 pMatChunk->setLit(false);
02897         }
02898     }
02899
02900     if(vFaceGroup[0]->getLightMode() == LMMeshColorLit ||
02901        vFaceGroup[0]->getLightMode() == LMVertexColorLit )
02902     {
02903         if(pGeo->getProperty(Geometry::NormalsIndex) == NULL)
02904             calcVertexNormals(pGeo);
02905     }
02906
02907     switch(vFaceGroup[0]->getDrawType())
02908     {
02909         case DTSolidCullBack:
02910         {
02911             PolygonChunkUnrecPtr pPolyChunk = PolygonChunk::create();
02912             pPolyChunk->setCullFace(GL_BACK);
02913
02914             pChunkMat->addChunk(pPolyChunk);
02915             break;
02916         }
02917
02918         case DTSolid:
02919         {
02920         // nothing to do
02921             break;
02922         }
02923
02924         case DTWireframeClosed:
02925         case DTWireframe:
02926         {
02927             PolygonChunkUnrecPtr pPolyChunk = PolygonChunk::create();
02928             pPolyChunk->setFrontMode(GL_LINE);
02929             pPolyChunk->setBackMode (GL_LINE);
02930
02931             pChunkMat->addChunk(pPolyChunk);
02932             break;
02933         }
02934
02935         default:
02936         {
02937             FWARNING(("OFMeshRecord::convertToNode: Unhandled draw "
02938                       "type [%d].\n", vFaceGroup[0]->getDrawType()));
02939             break;
02940         }
02941     }
02942
02943     pGeo->setMaterial(pChunkMat);
02944
02945     return returnValue;
02946 }
02947
02948 NodeTransitPtr OFGeometryContainer::convertGeometry(OFDatabase &oDB)
02949 {
02950     NodeTransitPtr returnValue(NULL);
02951
02952     std::vector< std::vector<OFFaceRecord *> > vFaceGroups;
02953
02954     groupFaces(vFaceGroups);
02955
02956     if(vFaceGroups.size() == 1 && _vMeshes.size() == 0)
02957     {
02958         returnValue = convertFaceGroup(vFaceGroups[0], oDB);
02959     }
02960     else if(vFaceGroups.size() == 0 && _vMeshes.size() == 1)
02961     {
02962         returnValue = _vMeshes[0]->convertToNode(oDB);
02963     }
02964     else if(vFaceGroups.size() > 0 || _vMeshes.size() > 0)
02965     {
02966         returnValue = Node::create();
02967         returnValue->setCore(Group::create());
02968
02969         for(UInt32 i = 0; i < vFaceGroups.size(); ++i)
02970         {
02971             returnValue->addChild(convertFaceGroup(vFaceGroups[i], oDB));
02972         }
02973
02974         for(UInt32 i = 0; i < _vMeshes.size(); ++i)
02975         {
02976             returnValue->addChild(_vMeshes[i]->convertToNode(oDB));
02977         }
02978     }
02979
02980     return returnValue;
02981 }
02982
02983 void OFGeometryContainer::dump(UInt32 uiIndent)
02984 {
02985     indentLog(uiIndent, PLOG);
02986     PLOG << "#NumFaces : " << _vFaces.size() << std::endl;
02987
02988     indentLog(uiIndent, PLOG);
02989     PLOG << "[" << std::endl;
02990
02991 #if 1
02992     uiIndent += 2;
02993
02994     for(UInt32 i = 0; i < _vFaces.size(); ++i)
02995     {
02996         _vFaces[i]->dump(uiIndent);
02997     }
02998
02999     uiIndent -= 2;
03000 #endif
03001 
03002     indentLog(uiIndent, PLOG);
03003     PLOG << "]" << std::endl;
03004
03005     indentLog(uiIndent, PLOG);
03006     PLOG << "#NumMeshes : " << _vMeshes.size() << std::endl;
03007
03008     indentLog(uiIndent, PLOG);
03009     PLOG << "[" << std::endl;
03010
03011     uiIndent += 2;
03012
03013     for(UInt32 i = 0; i < _vMeshes.size(); ++i)
03014     {
03015         _vMeshes[i]->dump(uiIndent);
03016     }
03017
03018     uiIndent -= 2;
03019
03020     indentLog(uiIndent, PLOG);
03021     PLOG << "]" << std::endl;
03022 }
03023
03024 //---------------------------------------------------------------------
03025 // OFGroupingRecord
03026 //---------------------------------------------------------------------
03027
03028
03029 OFGroupingRecord::OFGroupingRecord(const OFRecordHeader &oHeader) :
03030      Inherited(oHeader),
03031     _vChildren(       )
03032 {
03033 }
03034
03035 OFGroupingRecord::~OFGroupingRecord(void)
03036 {
03037     for(UInt32 i = 0; i < _vChildren.size(); ++i)
03038     {
03039         _vChildren[i] = NULL;
03040     }
03041
03042     _vChildren.clear();
03043 }
03044
03045 bool OFGroupingRecord::addChild (OFRecord *pChild)
03046 {
03047     if(pChild == NULL)
03048     {
03049         return false;
03050     }
03051
03052     bool rc = Inherited::addChild(pChild);
03053
03054     if(rc == false)
03055     {
03056         _vChildren.push_back(pChild);
03057     }
03058
03059     return true;
03060 }
03061
03062 void OFGroupingRecord::dump(UInt32 uiIndent)
03063 {
03064     indentLog(uiIndent, PLOG);
03065     PLOG << "#NumChildren : " << _vChildren.size() << std::endl;
03066
03067     indentLog(uiIndent, PLOG);
03068     PLOG << "[" << std::endl;
03069
03070     uiIndent += 2;
03071
03072     for(UInt32 i = 0; i < _vChildren.size(); ++i)
03073     {
03074         _vChildren[i]->dump(uiIndent);
03075     }
03076
03077     uiIndent -= 2;
03078
03079     indentLog(uiIndent, PLOG);
03080     PLOG << "]" << std::endl;
03081
03082     Inherited::dump(uiIndent);
03083 }
03084
03085 NodeTransitPtr OFGroupingRecord::convertToNode(OFDatabase &oDB)
03086 {
03087     NodeTransitPtr returnValue(NULL);
03088
03089     if(_vChildren.size() != 0 || _vFaces.size() != 0 || _vMeshes.size() != 0)
03090     {
03091         returnValue = Node::create();
03092
03093         returnValue->setCore(Group::create());
03094     }
03095     else
03096     {
03097         return returnValue;
03098     }
03099
03100     if(_vChildren.size() != 0)
03101     {
03102         NodeTransitPtr pChild;
03103
03104         for(UInt32 i = 0; i < _vChildren.size(); ++i)
03105         {
03106             pChild = _vChildren[i]->convertToNode(oDB);
03107
03108             if(pChild != NULL)
03109             {
03110                 returnValue->addChild(pChild);
03111             }
03112         }
03113     }
03114
03115     if(_vFaces.size() > 0 || _vMeshes.size() > 0)
03116     {
03117         returnValue->addChild(convertGeometry(oDB));
03118     }
03119
03120     return returnValue;
03121 }
03122
03123
03124 //---------------------------------------------------------------------
03125 // OFGroupRecord
03126 //---------------------------------------------------------------------
03127
03128 OFRecordTransitPtr OFGroupRecord::create(const OFRecordHeader &oHeader)
03129 {
03130     return OFRecordTransitPtr(new OFGroupRecord(oHeader));
03131 }
03132
03133 OFGroupRecord::OFGroupRecord(const OFRecordHeader &oHeader) :
03134     Inherited(oHeader)
03135 {
03136 }
03137
03138 OFGroupRecord::~OFGroupRecord(void)
03139 {
03140 }
03141
03142 bool OFGroupRecord::read(std::istream &is, OFDatabase &oDB)
03143 {
03144     return Inherited::read(is, oDB);
03145 }
03146
03147 UInt16 OFGroupRecord::getOpCode(void)
03148 {
03149     return OpCode;
03150 }
03151
03152 void OFGroupRecord::dump(UInt32 uiIndent)
03153 {
03154     indentLog(uiIndent, PLOG);
03155     PLOG << "GroupRecord" << std::endl;
03156
03157     indentLog(uiIndent, PLOG);
03158     PLOG << "{" << std::endl;
03159
03160     indentLog(uiIndent, PLOG);
03161     PLOG << "}" << std::endl;
03162
03163     Inherited::dump(uiIndent);
03164 }
03165
03166 OFRecordFactoryBase::RegisterRecord OFGroupRecord::_regHelper(
03167     &OFGroupRecord::create,
03168     OFGroupRecord::OpCode);
03169
03170
03171 //---------------------------------------------------------------------
03172 // OFLODRecord
03173 //---------------------------------------------------------------------
03174
03175 OFRecordTransitPtr OFLODRecord::create(const OFRecordHeader &oHeader)
03176 {
03177     return OFRecordTransitPtr(new OFLODRecord(oHeader));
03178 }
03179
03180 OFLODRecord::OFLODRecord(const OFRecordHeader &oHeader) :
03181     Inherited(oHeader)
03182 {
03183 }
03184
03185 OFLODRecord::~OFLODRecord(void)
03186 {
03187 }
03188
03189 bool OFLODRecord::read(std::istream &is, OFDatabase &oDB)
03190 {
03191     Inherited::readChar8(is, szASCIIId, 8);
03192     Inherited::readVal  (is, iPad1       );
03193     Inherited::readVal  (is, rSwitchIn   );
03194     Inherited::readVal  (is, rSwitchOut  );
03195     Inherited::readVal  (is, iSpecialEff1);
03196     Inherited::readVal  (is, iSpecialEff2);
03197     Inherited::readVal  (is, iFlags      );
03198     Inherited::readVal  (is, rCenterX    );
03199     Inherited::readVal  (is, rCenterY    );
03200     Inherited::readVal  (is, rCenterZ    );
03201     Inherited::readVal  (is, rTransRange );
03202
03203     if(_sLength >= 80)
03204         Inherited::readVal  (is, rSigSize    );
03205
03206     return is.good();
03207 }
03208
03209 UInt16 OFLODRecord::getOpCode(void)
03210 {
03211     return OpCode;
03212 }
03213
03214 void OFLODRecord::dump(UInt32 uiIndent)
03215 {
03216     indentLog(uiIndent, PLOG);
03217     PLOG << "LODRecord" << std::endl;
03218
03219     indentLog(uiIndent, PLOG);
03220     PLOG << "{" << std::endl;
03221
03222     uiIndent += 2;
03223
03224     indentLog(uiIndent, PLOG);
03225     PLOG << "rSwitchIn  : " << rSwitchIn  << std::endl;
03226
03227     indentLog(uiIndent, PLOG);
03228     PLOG << "rSwitchOut : " << rSwitchOut << std::endl;
03229
03230     uiIndent -= 2;
03231
03232     indentLog(uiIndent, PLOG);
03233     PLOG << "}" << std::endl;
03234
03235     Inherited::dump(uiIndent);
03236 }
03237
03238 NodeTransitPtr OFLODRecord::convertToNode(OFDatabase &oDB)
03239 {
03240     NodeTransitPtr returnValue(NULL);
03241
03242     if(_vChildren.size() != 0 || _vFaces.size() != 0)
03243     {
03244         returnValue            = Node::create();
03245         RangeLODUnrecPtr pCore = RangeLOD::create();
03246
03247         returnValue->setCore(pCore);
03248
03249         pCore->setSwitchIn (this->getSwitchIn ());
03250         pCore->setSwitchOut(this->getSwitchOut());
03251
03252         pCore->setCenter   (this->getCenter   ());
03253     }
03254     else
03255     {
03256         return returnValue;
03257     }
03258
03259     if(_vChildren.size() != 0)
03260     {
03261         NodeTransitPtr pChild;
03262
03263         for(UInt32 i = 0; i < _vChildren.size(); ++i)
03264         {
03265             pChild = _vChildren[i]->convertToNode(oDB);
03266
03267             if(pChild != NULL)
03268             {
03269                 returnValue->addChild(pChild);
03270             }
03271         }
03272     }
03273
03274     if(_vFaces.size() > 0 || _vMeshes.size() > 0)
03275     {
03276         returnValue->addChild(convertGeometry(oDB));
03277     }
03278
03279     return returnValue;
03280 }
03281
03282 Real64 OFLODRecord::getSwitchIn (void)
03283 {
03284     return rSwitchIn;
03285 }
03286
03287 Real64 OFLODRecord::getSwitchOut(void)
03288 {
03289     return rSwitchOut;
03290 }
03291
03292 Pnt3f  OFLODRecord::getCenter(void)
03293 {
03294     return Pnt3f(rCenterX, rCenterY, rCenterZ);
03295 }
03296
03297 OFRecordFactoryBase::RegisterRecord OFLODRecord::_regHelper(
03298     &OFLODRecord::create,
03299     OFLODRecord::OpCode);
03300
03301
03302 //---------------------------------------------------------------------
03303 // OFSwitchRecord
03304 //---------------------------------------------------------------------
03305
03306 OFRecordTransitPtr OFSwitchRecord::create(const OFRecordHeader &oHeader)
03307 {
03308     return OFRecordTransitPtr(new OFSwitchRecord(oHeader));
03309 }
03310
03311 OFSwitchRecord::OFSwitchRecord(const OFRecordHeader &oHeader) :
03312     Inherited(oHeader)
03313 {
03314 }
03315
03316 OFSwitchRecord::~OFSwitchRecord(void)
03317 {
03318 }
03319
03320 bool OFSwitchRecord::read(std::istream &is, OFDatabase &oDB)
03321 {
03322     Inherited::readChar8(is, szASCIIID, 8);
03323     Inherited::readVal  (is, szPad1      );
03324     Inherited::readVal  (is, iCurrMask   );
03325     Inherited::readVal  (is, iNumMask    );
03326     Inherited::readVal  (is, iMaskWords  );
03327
03328     vMask.resize(iNumMask);
03329
03330     for(Int32 i = 0; i < iNumMask; ++i)
03331     {
03332         vMask[i].resize(iMaskWords);
03333     }
03334
03335     for(Int32 i = 0; i < iNumMask; ++i)
03336     {
03337         for(Int32 j = 0; j < iMaskWords; ++j)
03338         {
03339             Inherited::readVal(is, vMask[i][j]);
03340         }
03341     }
03342
03343     return is.good();
03344 }
03345
03346 UInt16 OFSwitchRecord::getOpCode(void)
03347 {
03348     return OpCode;
03349 }
03350
03351
03352 void OFSwitchRecord::dump(UInt32 uiIndent)
03353 {
03354     indentLog(uiIndent, PLOG);
03355     PLOG << "SwitchRecord" << std::endl;
03356
03357     indentLog(uiIndent, PLOG);
03358     PLOG << "{" << std::endl;
03359
03360     uiIndent += 2;
03361
03362     indentLog(uiIndent, PLOG);
03363     PLOG << "iCurrMask  : " << iCurrMask  << std::endl;
03364     indentLog(uiIndent, PLOG);
03365     PLOG << "iNumMask   : " << iNumMask   << std::endl;
03366     indentLog(uiIndent, PLOG);
03367     PLOG << "iMaskWords : " << iMaskWords << std::endl;
03368
03369     PLOG.setf (std::ios::hex, std::ios::basefield);
03370
03371     for(Int32 i = 0; i < iNumMask; ++i)
03372     {
03373         indentLog(uiIndent, PLOG);
03374         PLOG << "Mask[" << i << "] : ";
03375
03376         for(Int32 j = 0; j < iMaskWords; ++j)
03377         {
03378             PLOG << vMask[i][j] << " ";
03379         }
03380         PLOG << std::endl;
03381     }
03382
03383     PLOG.setf(std::ios::dec, std::ios::basefield);
03384
03385     uiIndent -= 2;
03386
03387     indentLog(uiIndent, PLOG);
03388     PLOG << "}" << std::endl;
03389
03390     Inherited::dump(uiIndent);
03391 }
03392
03393 NodeTransitPtr OFSwitchRecord::convertToNode(OFDatabase &oDB)
03394 {
03395     NodeTransitPtr returnValue(NULL);
03396
03397     if(_vChildren.size() != 0 || _vFaces.size() != 0 || _vMeshes.size() != 0)
03398     {
03399         returnValue         = Node ::create();
03400         GroupUnrecPtr pCore = Group::create();
03401
03402         returnValue->setCore(pCore);
03403
03404 //        pCore->setSwitchIn (this->getSwitchIn ());
03405 //        pCore->setSwitchOut(this->getSwitchOut());
03406
03407 //        pCore->setCenter   (this->getCenter   ());
03408     }
03409     else
03410     {
03411         return returnValue;
03412     }
03413
03414     if(_vChildren.size() != 0)
03415     {
03416         NodeTransitPtr pChild;
03417
03418         for(UInt32 i = 0; i < _vChildren.size(); ++i)
03419         {
03420             pChild = _vChildren[i]->convertToNode(oDB);
03421
03422             if(pChild != NULL)
03423             {
03424                 returnValue->addChild(pChild);
03425             }
03426         }
03427     }
03428
03429     if(_vFaces.size() > 0 || _vMeshes.size() > 0)
03430     {
03431         returnValue->addChild(convertGeometry(oDB));
03432     }
03433
03434     return returnValue;
03435 }
03436
03437 OFRecordFactoryBase::RegisterRecord OFSwitchRecord::_regHelper(
03438     &OFSwitchRecord::create,
03439     OFSwitchRecord::OpCode);
03440
03441
03442
03443 //---------------------------------------------------------------------
03444 // OFObjectRecord
03445 //---------------------------------------------------------------------
03446
03447 OFRecordTransitPtr OFObjectRecord::create(const OFRecordHeader &oHeader)
03448 {
03449     return OFRecordTransitPtr(new OFObjectRecord(oHeader));
03450 }
03451
03452 OFObjectRecord::OFObjectRecord(const OFRecordHeader &oHeader) :
03453      Inherited(oHeader),
03454     _vChildren(       )
03455 {
03456 }
03457
03458 OFObjectRecord::~OFObjectRecord(void)
03459 {
03460     for(UInt32 i = 0; i < _vChildren.size(); ++i)
03461     {
03462         _vChildren[i] = NULL;
03463     }
03464
03465     _vChildren.clear();
03466 }
03467
03468 bool OFObjectRecord::addChild (OFRecord *pChild)
03469 {
03470     if(pChild == NULL)
03471     {
03472         return false;
03473     }
03474
03475     bool rc = Inherited::addChild(pChild);
03476
03477     if(rc == false)
03478     {
03479         _vChildren.push_back(pChild);
03480     }
03481
03482     return true;
03483 }
03484
03485 void OFObjectRecord::dump(UInt32 uiIndent)
03486 {
03487     indentLog(uiIndent, PLOG);
03488     PLOG << "ObjectRecord" << std::endl;
03489
03490     indentLog(uiIndent, PLOG);
03491     PLOG << "{" << std::endl;
03492
03493     indentLog(uiIndent, PLOG);
03494     PLOG << "}" << std::endl;
03495
03496     indentLog(uiIndent, PLOG);
03497     PLOG << "#NumChildren : " << _vChildren.size() << std::endl;
03498
03499     indentLog(uiIndent, PLOG);
03500     PLOG << "[" << std::endl;
03501
03502     uiIndent += 2;
03503
03504     for(UInt32 i = 0; i < _vChildren.size(); ++i)
03505     {
03506         _vChildren[i]->dump(uiIndent);
03507     }
03508
03509     uiIndent -= 2;
03510
03511     indentLog(uiIndent, PLOG);
03512     PLOG << "]" << std::endl;
03513
03514
03515     Inherited::dump(uiIndent);
03516 }
03517
03518 bool OFObjectRecord::read(std::istream &is, OFDatabase &oDB)
03519 {
03520     return Inherited::read(is, oDB);
03521 }
03522
03523
03524 UInt16 OFObjectRecord::getOpCode(void)
03525 {
03526     return OpCode;
03527 }
03528
03529 NodeTransitPtr OFObjectRecord::convertToNode(OFDatabase &oDB)
03530 {
03531     return Inherited::convertGeometry(oDB);
03532 }
03533
03534 OFRecordFactoryBase::RegisterRecord OFObjectRecord::_regHelper(
03535     &OFObjectRecord::create,
03536     OFObjectRecord::OpCode);
03537
03538
03539 //---------------------------------------------------------------------
03540 // OFExternalReferenceRecord
03541 //---------------------------------------------------------------------
03542
03543 OFRecordTransitPtr OFExternalReferenceRecord::create(
03544     const OFRecordHeader &oHeader)
03545 {
03546     return OFRecordTransitPtr(new OFExternalReferenceRecord(oHeader));
03547 }
03548
03549 OFExternalReferenceRecord::OFExternalReferenceRecord(
03550     const OFRecordHeader &oHeader) :
03551
03552     Inherited(oHeader)
03553 {
03554 }
03555
03556 OFExternalReferenceRecord::~OFExternalReferenceRecord(void)
03557 {
03558 }
03559
03560 bool OFExternalReferenceRecord::read(std::istream &is, OFDatabase &oDB)
03561 {
03562     Inherited::readChar8(is, szFilename, 200);
03563     Inherited::readVal  (is, iPad1          );
03564     Inherited::readVal  (is, iFlags         );
03565     Inherited::readVal  (is, iViewAsBBox    );
03566     Inherited::readVal  (is, iPad2          );
03567
03568     return is.good();
03569 }
03570
03571 UInt16 OFExternalReferenceRecord::getOpCode(void)
03572 {
03573     return OpCode;
03574 }
03575
03576 void OFExternalReferenceRecord::dump(UInt32 uiIndent)
03577 {
03578     indentLog(uiIndent, PLOG);
03579     PLOG << "ExternalReference : " << std::endl;
03580
03581     indentLog(uiIndent, PLOG);
03582     PLOG << "{" << std::endl;
03583
03584     uiIndent += 2;
03585
03586     indentLog(uiIndent, PLOG);
03587     PLOG << "Filename : " << szFilename << std::endl;
03588
03589     PLOG.setf (std::ios::hex, std::ios::basefield);
03590
03591     indentLog(uiIndent, PLOG);
03592     PLOG << "FullFlags : " << iFlags << std::endl;
03593
03594     PLOG.setf (std::ios::dec, std::ios::basefield);
03595
03596     indentLog(uiIndent, PLOG);
03597     PLOG << "Flags : "
03598          << "(CP : "  << ((iFlags & 0x80000000) >> 31) << ") "
03599          << "(MP : "  << ((iFlags & 0x40000000) >> 30) << ") "
03600          << "(TP : "  << ((iFlags & 0x20000000) >> 29) << ") "
03601          << "(LP : "  << ((iFlags & 0x10000000) >> 28) << ") "
03602          << "(SP : "  << ((iFlags & 0x08000000) >> 27) << ") "
03603          << "(LSP : " << ((iFlags & 0x04000000) >> 26) << ") "
03604          << "(LPP : " << ((iFlags & 0x02000000) >> 25) << ") "
03605          << "(SHP : " << ((iFlags & 0x01000000) >> 24) << ") "
03606          << std::endl;
03607
03608     uiIndent -= 2;
03609
03610     indentLog(uiIndent, PLOG);
03611     PLOG << "}" << std::endl;
03612 }
03613
03614 NodeTransitPtr OFExternalReferenceRecord::convertToNode(OFDatabase &oDB)
03615 {
03616     NodeTransitPtr returnValue(NULL);
03617
03618     PathHandler *pHandler = SceneFileHandler::the()->getPathHandler();
03619
03620     if(pHandler != NULL)
03621     {
03622         std::string szFilenameResolved = pHandler->findFile(szFilename);
03623
03624         if(szFilenameResolved.empty() == true)
03625         {
03626             FWARNING(("OFExternalReferenceRecord::convertToNode: Could not "
03627                       "find file [%s].\n", szFilename));
03628
03629             return returnValue;
03630         }
03631
03632         pHandler->pushState();
03633
03634         pHandler->setBaseFile(szFilenameResolved.c_str());
03635
03636         std::ifstream is;
03637
03638         is.open(szFilenameResolved.c_str(), std::ios::binary);
03639
03640         returnValue =
03641             OpenFlightSceneFileType::the().read(is,
03642                                                 szFilenameResolved.c_str());
03643
03644         pHandler->popState();
03645
03646     }
03647     else
03648     {
03649         FFATAL(("OFExternalReferenceRecord::convertToNode: No PathHandler.\n"));
03650     }
03651
03652     return returnValue;
03653 }
03654
03655 OFRecordFactoryBase::RegisterRecord OFExternalReferenceRecord::_regHelper(
03656     &OFExternalReferenceRecord::create,
03657     OFExternalReferenceRecord::OpCode);
03658
03659 OSG_END_NAMESPACE