fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / OpenFlight / OSGOFRecords.cpp
blob5abb61edc25ea264f1c23f3b8408e96e89ec3400
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2008 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include "OSGOFRecords.h"
41 #include "OSGSingletonHolder.ins"
42 #include "OSGGroup.h"
43 #include "OSGNode.h"
45 #include "OSGOFDatabase.h"
46 #include "OSGOpenFlightLog.h"
48 OSG_BEGIN_NAMESPACE
50 OSG_SINGLETON_INST(OFRecordFactoryBase, addPostFactoryExitFunction)
52 template class SingletonHolder<OFRecordFactoryBase>;
55 //---------------------------------------------------------------------
56 // OFRecordFactoryBase
57 //---------------------------------------------------------------------
59 OFRecordFactoryBase::RegisterRecord::RegisterRecord(CreateRecord fCreate,
60 UInt16 sRecordOpCode)
62 OFRecordFactory::the()->registerRecord(fCreate, sRecordOpCode);
66 OFRecordFactoryBase::OFRecordFactoryBase(void) :
67 _mRegisteredRecords()
71 OFRecordFactoryBase::~OFRecordFactoryBase(void)
75 void OFRecordFactoryBase::registerRecord(CreateRecord fHelper,
76 UInt16 sRecordOpCode)
78 if(fHelper == NULL)
79 return;
81 NameRecordCreateMap::iterator mRecordIt =
82 _mRegisteredRecords.find(sRecordOpCode);
85 if(mRecordIt == _mRegisteredRecords.end())
87 _mRegisteredRecords[sRecordOpCode] = fHelper;
89 PINFO << "Record registered for "
90 << sRecordOpCode
91 << std::endl;
93 else
95 PWARNING << "Record already registered for %s "
96 << sRecordOpCode
97 << std::endl;
101 OFRecordTransitPtr OFRecordFactoryBase::createRecord(
102 const OFRecordHeader &oHeader, OFDatabase &oDB)
104 NameRecordCreateMap::iterator mRecordIt =
105 _mRegisteredRecords.find(oHeader.sOpCode);
107 OFRecordTransitPtr returnValue(NULL);
109 if(mRecordIt != _mRegisteredRecords.end())
111 returnValue = (*mRecordIt).second(oHeader, oDB);
113 else
115 returnValue = new OFUnknownRecord(oHeader, oDB);
118 return returnValue;
121 //---------------------------------------------------------------------
122 // OFRecord
123 //---------------------------------------------------------------------
125 /*! \nohierarchy
127 struct OFOpCodeDesc
129 UInt16 sOpCode;
130 const Char8 *szDesc;
134 OFOpCodeDesc aOpCodeDescs[] =
136 {1, "Header" },
137 {2, "Group" },
138 {4, "Object" },
139 {5, "Face" },
140 {10, "Push Level" },
141 {11, "Pop Level" },
142 {14, "Degree of Freedom" },
143 {19, "Push Subface" },
144 {20, "Pop Subface" },
145 {21, "Push Extension" },
146 {22, "Pop Extension" },
147 {23, "Continuation" },
148 {31, "Comment" },
149 {32, "Color Palette" },
150 {33, "Long ID" },
151 {49, "Matrix" },
152 {50, "Vector" },
153 {52, "Multitexture" },
154 {53, "UV List" },
155 {55, "Binary Separating Plane" },
156 {60, "Replicate" },
157 {61, "Instance Reference" },
158 {62, "Instance Definition" },
159 {63, "External Reference" },
160 {64, "Texture Palette" },
161 {67, "Vertex Palette" },
162 {68, "Vertex with Color" },
163 {69, "Vertex with Color and Normal" },
164 {70, "Vertex with Color, Normal and UV" },
165 {71, "Vertex with Color and UV" },
166 {72, "Vertex List" },
167 {73, "Level of Detail" },
168 {74, "Bounding Box" },
169 {76, "Rotate About Edge" },
170 {78, "Translate" },
171 {79, "Scale" },
172 {80, "Rotate About Point" },
173 {81, "Rotate and/or Scale to Point" },
174 {82, "Put" },
175 {83, "Eyepoint and Trackplane Palette" },
176 {84, "Mesh" },
177 {85, "Local Vertex Pool" },
178 {86, "Mesh Primitive" },
179 {87, "Road Segment" },
180 {88, "Road Zone" },
181 {89, "Morph Vertex List" },
182 {90, "Linkage Palette" },
183 {91, "Sound" },
184 {92, "Road Path" },
185 {93, "Sound Palette" },
186 {94, "General Matrix" },
187 {95, "Text" },
188 {96, "Switch" },
189 {97, "Line Style Palette" },
190 {98, "Clip Region" },
191 {100, "Extension" },
192 {101, "Light Source" },
193 {102, "Light Source Palette" },
194 {103, "Reserved" },
195 {104, "Reserved" },
196 {105, "Bounding Sphere" },
197 {106, "Bounding Cylinder" },
198 {107, "Bounding Convex Hull" },
199 {108, "Bounding Volume Center" },
200 {109, "Bounding Volume Orientation" },
201 {110, "Reserved" },
202 {111, "Light Point" },
203 {112, "Texture Mapping Palette" },
204 {113, "Material Palette" },
205 {114, "Name Table" },
206 {115, "Continuously Adaptive Terrain (CAT)"},
207 {116, "CAT Data" },
208 {117, "Reserved" },
209 {118, "Reserved" },
210 {119, "Bounding Histogram" },
211 {120, "Reserved" },
212 {121, "Reserved" },
213 {122, "Push Attribute" },
214 {123, "Pop Attribute" },
215 {124, "Reserved" },
216 {125, "Reserved" },
217 {126, "Curve" },
218 {127, "Road Construction" },
219 {128, "Light Point Appearance Palette" },
220 {129, "Light Point Animation Palette" },
221 {130, "Indexed Light Point" },
222 {131, "Light Point System" },
223 {132, "Indexed String" },
224 {133, "Shader Palette" },
225 {134, "Reserved" },
226 {135, "Extended Material Header" },
227 {136, "Extended Material Ambient" },
228 {137, "Extended Material Diffuse" },
229 {138, "Extended Material Specular" },
230 {139, "Extended Material Emissive" },
231 {140, "Extended Material Alpha" },
232 {141, "Extended Material Light Map" },
233 {142, "Extended Material Normal Map" },
234 {143, "Extended Material Bump Map" },
235 {144, "Reserved" },
236 {145, "Extended Material Shadow Map" },
237 {146, "Reserved" },
238 {147, "Extended Material Reflection Map" },
240 { 0, "Reached last -> Unknown" }
243 const Char8 *aCategoryNames[] =
245 "Control",
246 "Primary",
247 "Ancillary",
248 "Continuation",
250 "Undefined"
253 #if 0
254 Obsolete
256 3 Level of Detail (single precision floating point, replaced by Opcode 73)
257 6 Vertex with ID (scaled integer coordinates, replaced by Opcodes 68-71)
258 7 Short Vertex w/o ID (scaled integer coordinates, replaced by Opcodes 68-71)
259 8 Vertex with Color (scaled integer coordinates, replaced by Opcodes 68-71)
260 9 Vertex with Color and Normal (scaled integer coordinates, replaced by Opcodes 68-71)
261 12 Translate (replaced by Opcode 78)
262 13 Degree of Freedom (scaled integer coordinates, replaced by Opcode 14)
263 16 Instance Reference (replaced by Opcode 61)
264 17 Instance Definition (replaced by Opcode 62)
265 40 Translate (replaced by Opcode 78)
266 41 Rotate about Point (replaced by Opcode 80)
267 42 Rotate about Edge (replaced by Opcode 76)
268 43 Scale (replaced by Opcode 79)
269 44 Translate (replaced by Opcode 78)
270 45 Scale nonuniform (replaced by Opcode 79)
271 46 Rotate about Point (replaced by Opcode 80)
272 47 Rotate and/or Scale to Point (replaced by Opcode 81)
273 48 Put (replaced by Opcode 82)
274 51 Bounding Box (replaced by Opcode 74)
275 65 Eyepoint Palette (only eyepoints, replaced by Opcode 83)
276 66 Material Palette (fixed size 64 entries, replaced by Opcode 80)
277 77 Scale (replaced by Opcode 79)
279 #endif
282 /* static */
283 const Char8 *OFRecord::getOpCodeString(UInt16 sOpCode)
285 OFOpCodeDesc *pDesc = aOpCodeDescs;
287 while(pDesc->sOpCode != 0)
289 if(pDesc->sOpCode == sOpCode)
291 break;
294 ++pDesc;
297 return pDesc->szDesc;
300 /* static */
301 const Char8 *OFRecord::getCategoryString(CategoryE cat)
303 return aCategoryNames[cat];
306 const Char8 *OFRecord::getOpCodeString(void) const
308 return getOpCodeString(getOpCode());
311 const Char8 *OFRecord::getCategoryString(void) const
313 return getCategoryString(getCategory());
316 bool OFRecord::read(std::istream &is)
318 if(_sLength > 4)
320 return readContinue(is, _sLength - 4);
322 else
324 return is.good();
328 bool OFRecord::readContinue(std::istream &is, UInt16 uiLength)
330 std::vector<char> tmpBuf;
332 tmpBuf.resize(uiLength);
334 is.read(&(tmpBuf.front()), uiLength);
336 return is.good();
339 NodeTransitPtr OFRecord::convertToNode(void)
341 NodeTransitPtr returnValue(NULL);
343 return returnValue;
346 void OFRecord::dump(UInt32 uiIndent) const
350 OFRecord::OFRecord(const OFRecordHeader &oHeader,
351 OFDatabase &oDB ) :
352 Inherited( ),
353 _oDB (oDB ),
354 _sLength (oHeader.sLength)
358 OFRecord::~OFRecord(void)
362 //---------------------------------------------------------------------
363 // OFPrimaryRecord
364 //---------------------------------------------------------------------
366 /* static */
367 OFPrimaryRecord::CategoryE OFPrimaryRecord::getClassCategory(void)
369 return Category;
372 /* virtual */
373 OFPrimaryRecord::CategoryE OFPrimaryRecord::getCategory(void) const
375 return getClassCategory();
378 /* virtual */
379 bool OFPrimaryRecord::addChild(OFRecord *pChild)
381 if(pChild == NULL)
382 return false;
384 OSG_OPENFLIGHT_LOG(("OFPrimaryRecord::addChild: this "
385 "[%u][%s][%s] - child [%u][%s][%s]\n",
386 getOpCode(),
387 getOpCodeString(),
388 getCategoryString(),
389 pChild->getOpCode(),
390 pChild->getOpCodeString(),
391 pChild->getCategoryString()));
393 bool returnValue(false);
395 if(pChild->getCategory() == RC_Primary)
397 OFPrimaryRecord *pPrimChild = dynamic_cast<OFPrimaryRecord *>(pChild);
399 _primaryChildren.push_back(pPrimChild);
401 returnValue = true;
403 else if(pChild->getCategory() == RC_Ancillary)
405 OFAncillaryRecord *pAncilChild =
406 dynamic_cast<OFAncillaryRecord *>(pChild);
408 _ancillaryChildren.push_back(pAncilChild);
410 returnValue = true;
412 else
414 FFATAL(("OFPrimaryRecord::addChild: attempting to add child "
415 "[%u][%s] with unsupported category [%s].\n",
416 pChild->getOpCode(),
417 pChild->getOpCodeString(),
418 pChild->getCategoryString()));
421 return returnValue;
424 /* virtual */
425 void OFPrimaryRecord::dump(UInt32 uiIndent) const
427 indentLog(uiIndent, PLOG);
428 PLOG << "#PrimaryChildren " << _primaryChildren.size() << std::endl;
430 indentLog(uiIndent, PLOG);
431 PLOG << "[" << std::endl;
433 uiIndent += 2;
435 for(UInt32 i = 0; i < _primaryChildren.size(); ++i)
437 _primaryChildren[i]->dump(uiIndent);
440 uiIndent -= 2;
442 indentLog(uiIndent, PLOG);
443 PLOG << "]" << std::endl;
445 indentLog(uiIndent, PLOG);
446 PLOG << "#AncillaryChildren " << _ancillaryChildren.size() << std::endl;
448 indentLog(uiIndent, PLOG);
449 PLOG << "[" << std::endl;
451 uiIndent += 2;
453 for(UInt32 i = 0; i < _ancillaryChildren.size(); ++i)
455 _ancillaryChildren[i]->dump(uiIndent);
458 uiIndent -= 2;
460 indentLog(uiIndent, PLOG);
461 PLOG << "]" << std::endl;
465 OFPrimaryRecord::OFPrimaryRecord(const OFRecordHeader &oHeader,
466 OFDatabase &oDB ) :
467 Inherited (oHeader, oDB),
468 _primaryChildren (),
469 _ancillaryChildren()
473 /* virtual */
474 OFPrimaryRecord::~OFPrimaryRecord(void)
478 //---------------------------------------------------------------------
479 // OFAncillaryRecord
480 //---------------------------------------------------------------------
482 /* static */
483 OFAncillaryRecord::CategoryE OFAncillaryRecord::getClassCategory(void)
485 return Category;
488 /* virtual */
489 OFAncillaryRecord::CategoryE OFAncillaryRecord::getCategory(void) const
491 return getClassCategory();
494 /* virtual */
495 bool OFAncillaryRecord::addChild(OFRecord *pChild)
497 FFATAL(("OFAncillaryRecord::addChild: called for [%u][%s] "
498 "with child [%u][%s] - this should never happen.\n",
499 getOpCode(), getOpCodeString(),
500 (pChild != NULL ? pChild->getOpCode() : 0),
501 (pChild != NULL ? pChild->getOpCodeString() : "NULL")));
503 return false;
506 /* virtual */
507 NodeTransitPtr OFAncillaryRecord::convertToNode(void)
509 FFATAL(("OFAncillaryRecord::convertToNode: called for [%u][%s] "
510 "- this should never happen.\n",
511 getOpCode(), getOpCodeString()));
513 return NodeTransitPtr(NULL);
516 /* virtual */
517 NodeTransitPtr OFAncillaryRecord::convert(Node *pNode)
519 FWARNING(("OFAncillaryRecord::convert: Not implemented for [%u][%s].\n",
520 getOpCode(), getOpCodeString()));
522 return NodeTransitPtr(NULL);
525 OFAncillaryRecord::OFAncillaryRecord(const OFRecordHeader &oHeader,
526 OFDatabase &oDB ) :
527 Inherited(oHeader, oDB)
531 /* virtual */
532 OFAncillaryRecord::~OFAncillaryRecord(void)
536 //---------------------------------------------------------------------
537 // OFControlRecord
538 //---------------------------------------------------------------------
540 /* static */
541 OFControlRecord::CategoryE OFControlRecord::getClassCategory(void)
543 return Category;
546 /* virtual */
547 OFControlRecord::CategoryE OFControlRecord::getCategory(void) const
549 return getClassCategory();
552 /* virtual */
553 bool OFControlRecord::addChild(OFRecord *pChild)
555 FFATAL(("OFControlRecord::addChild: This should never be called\n"));
557 return false;
560 OFControlRecord::OFControlRecord(const OFRecordHeader &oHeader,
561 OFDatabase &oDB ) :
562 Inherited(oHeader, oDB)
566 /* virtual */
567 OFControlRecord::~OFControlRecord(void)
571 //---------------------------------------------------------------------
572 // OFUnknownRecord
573 //---------------------------------------------------------------------
575 OFUnknownRecord::OFUnknownRecord(const OFRecordHeader &oHeader,
576 OFDatabase &oDB ) :
577 Inherited(oHeader, oDB ),
578 _sOpCode (oHeader.sOpCode),
579 _vChildren( )
583 OFUnknownRecord::~OFUnknownRecord(void)
587 bool OFUnknownRecord::read(std::istream &is)
589 OSG_OPENFLIGHT_LOG(("OFUnknownRecord::read op [%u][%s] len [%u]\n",
590 _sOpCode, getOpCodeString(_sOpCode), _sLength));
592 static std::vector<char> tmpBuf;
594 if(_sLength > 4)
596 tmpBuf.resize(_sLength);
598 is.read(&(tmpBuf.front()), _sLength - 4);
601 return is.good();
604 bool OFUnknownRecord::addChild(OFRecord *pChild)
606 if(pChild == NULL)
607 return false;
609 OSG_OPENFLIGHT_LOG(("OFUnknownRecord::addChild: this [%u][%s][%s] "
610 "child [%u][%s][%s]\n",
611 getOpCode(),
612 getCategoryString(),
613 getOpCodeString(),
614 pChild->getOpCode(),
615 pChild->getCategoryString(),
616 pChild->getOpCodeString() ));
618 _vChildren.push_back(pChild);
620 return true;
623 /* virtual */
624 UInt16 OFUnknownRecord::getOpCode(void) const
626 return _sOpCode;
629 /* virtual */
630 OFUnknownRecord::CategoryE OFUnknownRecord::getCategory(void) const
632 return RC_Undefined;
635 NodeTransitPtr OFUnknownRecord::convertToNode(void)
637 NodeTransitPtr returnValue(NULL);
639 if(_vChildren.empty() == false)
641 returnValue = makeCoredNode<Group>();
643 for(UInt32 i = 0; i < _vChildren.size(); ++i)
644 returnValue->addChild(_vChildren[i]->convertToNode());
647 return returnValue;
650 void OFUnknownRecord::dump(UInt32 uiIndent) const
652 indentLog(uiIndent, PLOG);
653 PLOG << "OFUnknownRecord - " << _sOpCode
654 << " - " << getOpCodeString(_sOpCode)
655 << std::endl;
658 OSG_END_NAMESPACE