1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12 */ 13 14 // 15 // OpenFlight (R) loader for OpenSceneGraph 16 // 17 // Copyright (C) 2005-2007 Brede Johansen 18 // 19 20 #include <assert.h> 21 #include <osg/Light> 22 #include <osg/Texture2D> 23 #include <osg/TexEnv> 24 #include <osg/BlendFunc> 25 #include <osgSim/LightPointNode> 26 #include <osgDB/ReadFile> 27 #include <osgDB/FileUtils> 28 #include "Registry.h" 29 #include "Document.h" 30 #include "AttrData.h" 31 #include "RecordInputStream.h" 32 33 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) 34 #define GL_RGB5 0x8050 35 #define GL_RGBA4 0x8056 36 #define GL_RGBA8 0x8058 37 #define GL_RGBA12 0x805A 38 #define GL_RGB12 0x8053 39 #define GL_LUMINANCE12_ALPHA4 0x8046 40 #define GL_LUMINANCE12_ALPHA12 0x8047 41 #define GL_INTENSITY16 0x804D 42 #endif 43 44 #if defined(OSG_GL3_AVAILABLE) 45 #define GL_LUMINANCE12_ALPHA4 0x8046 46 #define GL_LUMINANCE12_ALPHA12 0x8047 47 #define GL_INTENSITY16 0x804D 48 #endif 49 50 namespace flt { 51 52 class VertexPalette : public Record 53 { 54 public: 55 VertexPalette()56 VertexPalette() {} 57 58 META_Record(VertexPalette) 59 60 protected: 61 ~VertexPalette()62 virtual ~VertexPalette() {} 63 readRecord(RecordInputStream & in,Document & document)64 virtual void readRecord(RecordInputStream& in, Document& document) 65 { 66 uint32 paletteSize = in.readUInt32(); 67 68 // Entries in vertex pool found by offset from start of this record. 69 const uint32 RECORD_HEADER_SIZE = 4; 70 const uint32 OFFSET = RECORD_HEADER_SIZE+sizeof(paletteSize); 71 72 std::string buffer(paletteSize,'\0'); 73 if (OFFSET < paletteSize) 74 { 75 in.read(&buffer[OFFSET], paletteSize-OFFSET); 76 } 77 78 // Keep a copy of the vertex pool in memory for later reference. 79 document.setVertexPool(new VertexPool(buffer)); 80 } 81 }; 82 83 REGISTER_FLTRECORD(VertexPalette, VERTEX_PALETTE_OP) 84 85 86 87 class ColorPalette : public Record 88 { 89 public: 90 ColorPalette()91 ColorPalette() {} 92 93 META_Record(ColorPalette) 94 95 protected: 96 ~ColorPalette()97 virtual ~ColorPalette() {} 98 readRecord(RecordInputStream & in,Document & document)99 virtual void readRecord(RecordInputStream& in, Document& document) 100 { 101 if (document.getColorPoolParent()) 102 // Using parent's color pool -- ignore this record. 103 return; 104 105 if (document.version() > VERSION_13) 106 { 107 bool oldVersion = false; 108 bool colorNameSection = in.getRecordSize() > 4228; 109 int maxColors = (document.version()>=VERSION_15_1) ? 1024 : 512; 110 111 // It might be less. 112 if (!colorNameSection) 113 { 114 // Max colors calculated by record size. 115 int maxColorsByRecordSize = (in.getRecordBodySize()-128) / 4; 116 if (maxColorsByRecordSize < maxColors) 117 maxColors = maxColorsByRecordSize; 118 } 119 120 ColorPool* cp = new ColorPool(oldVersion,maxColors); 121 document.setColorPool(cp); 122 123 in.forward(128); 124 for (int i=0; i<maxColors; i++) 125 { 126 uint8 alpha = in.readUInt8(1); 127 uint8 blue = in.readUInt8(1); 128 uint8 green = in.readUInt8(1); 129 uint8 red = in.readUInt8(1); 130 131 (*cp)[i] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,(float)alpha/255); 132 } 133 } 134 else // version <= 13 135 { 136 bool oldVersion = true; 137 int maxColors = 32+56; 138 139 ColorPool* cp = new ColorPool(oldVersion,maxColors); 140 document.setColorPool(cp); 141 142 // variable intensity 143 for (int i=0; i < 32; i++) 144 { 145 uint16 red = in.readUInt16(1); 146 uint16 green = in.readUInt16(1); 147 uint16 blue = in.readUInt16(1); 148 (*cp)[i] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,1); 149 } 150 151 // fixed intensity 152 for (int i=0; i < 56; i++) 153 { 154 uint16 red = in.readUInt16(1); 155 uint16 green = in.readUInt16(1); 156 uint16 blue = in.readUInt16(1); 157 (*cp)[i+32] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,1); 158 } 159 } 160 } 161 }; 162 163 164 REGISTER_FLTRECORD(ColorPalette, COLOR_PALETTE_OP) 165 166 167 168 class NameTable : public Record 169 { 170 public: 171 NameTable()172 NameTable() {} 173 174 META_Record(NameTable) 175 176 protected: 177 ~NameTable()178 virtual ~NameTable() {} 179 readRecord(RecordInputStream &,Document &)180 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) 181 { 182 } 183 }; 184 185 REGISTER_FLTRECORD(NameTable, NAME_TABLE_OP) 186 187 188 189 class MaterialPalette : public Record 190 { 191 public: 192 MaterialPalette()193 MaterialPalette() {} 194 195 META_Record(MaterialPalette) 196 197 protected: 198 ~MaterialPalette()199 virtual ~MaterialPalette() {} 200 readRecord(RecordInputStream & in,Document & document)201 virtual void readRecord(RecordInputStream& in, Document& document) 202 { 203 if (document.getMaterialPoolParent()) 204 // Using parent's material pool -- ignore this record. 205 return; 206 207 int32 index = in.readInt32(); 208 std::string name = in.readString(12); 209 /*uint32 flags =*/ in.readUInt32(); 210 osg::Vec3f ambient = in.readVec3f(); 211 osg::Vec3f diffuse = in.readVec3f(); 212 osg::Vec3f specular = in.readVec3f(); 213 osg::Vec3f emissive = in.readVec3f(); 214 float32 shininess = in.readFloat32(); 215 float32 alpha = in.readFloat32(); 216 217 osg::Material* material = new osg::Material; 218 material->setName(name); 219 material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(ambient,alpha)); 220 material->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(diffuse,alpha)); 221 material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(specular,alpha)); 222 material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(emissive,alpha)); 223 224 if (shininess>=0.0f) 225 { 226 material->setShininess(osg::Material::FRONT_AND_BACK,shininess); 227 } 228 else 229 { 230 OSG_INFO<<"Warning: OpenFlight shininess value out of range: "<<shininess<<std::endl; 231 } 232 233 MaterialPool* mp = document.getOrCreateMaterialPool(); 234 (*mp)[index] = material; 235 } 236 }; 237 238 REGISTER_FLTRECORD(MaterialPalette, MATERIAL_PALETTE_OP) 239 240 241 242 class OldMaterialPalette : public Record 243 { 244 public: 245 OldMaterialPalette()246 OldMaterialPalette() {} 247 248 META_Record(OldMaterialPalette) 249 250 protected: 251 ~OldMaterialPalette()252 virtual ~OldMaterialPalette() {} 253 readRecord(RecordInputStream & in,Document & document)254 virtual void readRecord(RecordInputStream& in, Document& document) 255 { 256 if (document.getMaterialPoolParent()) 257 // Using parent's material pool -- ignore this record. 258 return; 259 260 for (int i=0; i < 64; i++) 261 { 262 osg::Vec3f ambient = in.readVec3f(); 263 osg::Vec3f diffuse = in.readVec3f(); 264 osg::Vec3f specular = in.readVec3f(); 265 osg::Vec3f emissive = in.readVec3f(); 266 float32 shininess = in.readFloat32(); 267 float32 alpha = in.readFloat32(); 268 /*uint32 flags =*/ in.readUInt32(); 269 std::string name = in.readString(12); 270 in.forward(4*28); 271 272 osg::Material* material = new osg::Material; 273 material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(ambient,alpha)); 274 material->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(diffuse,alpha)); 275 material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(specular,alpha)); 276 material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(emissive,alpha)); 277 278 if (shininess>=0.0f) 279 { 280 material->setShininess(osg::Material::FRONT_AND_BACK,shininess); 281 } 282 else 283 { 284 OSG_INFO<<"Warning: OpenFlight shininess value out of range: "<<shininess<<std::endl; 285 } 286 287 MaterialPool* mp = document.getOrCreateMaterialPool(); 288 (*mp)[i] = material; 289 } 290 } 291 292 }; 293 294 REGISTER_FLTRECORD(OldMaterialPalette, OLD_MATERIAL_PALETTE_OP) 295 296 297 298 class TexturePalette : public Record 299 { 300 public: 301 TexturePalette()302 TexturePalette() {} 303 304 META_Record(TexturePalette) 305 306 protected: 307 ~TexturePalette()308 virtual ~TexturePalette() {} 309 convertWrapMode(int32 attrWrapMode,const Document & document) const310 osg::Texture2D::WrapMode convertWrapMode(int32 attrWrapMode, const Document& document) const 311 { 312 osg::Texture2D::WrapMode osgWrapMode = osg::Texture2D::REPEAT; 313 switch (attrWrapMode) 314 { 315 case AttrData::WRAP_CLAMP: 316 if (document.getReplaceClampWithClampToEdge()) 317 osgWrapMode = osg::Texture2D::CLAMP_TO_EDGE; 318 else 319 osgWrapMode = osg::Texture2D::CLAMP; 320 break; 321 case AttrData::WRAP_MIRRORED_REPEAT: 322 osgWrapMode = osg::Texture2D::MIRROR; 323 break; 324 case AttrData::WRAP_REPEAT: 325 osgWrapMode = osg::Texture2D::REPEAT; 326 break; 327 } 328 329 return osgWrapMode; 330 } 331 readTexture(const std::string & filename,const Document & document) const332 osg::StateSet* readTexture(const std::string& filename, const Document& document) const 333 { 334 osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(filename,document.getOptions()); 335 if (!image) return NULL; 336 337 // Create stateset to hold texture and attributes. 338 osg::StateSet* stateset = new osg::StateSet; 339 340 osg::Texture2D* texture = new osg::Texture2D; 341 texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT); 342 texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT); 343 texture->setResizeNonPowerOfTwoHint(true); 344 texture->setImage(image.get()); 345 stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); 346 347 // Since the .attr file is optional according to the OpenFlight spec, check to see 348 // if the file exists before reading it, to avoid printing an unnecessary warning. 349 std::string attrname = filename + ".attr"; 350 if (!osgDB::fileExists(attrname)) 351 return stateset; 352 353 // Read optional attribute file 354 osg::ref_ptr<AttrData> attr = osgDB::readRefFile<AttrData>(attrname,document.getOptions()); 355 if (attr.valid()) 356 { 357 // Wrap mode 358 osg::Texture2D::WrapMode wrap_s = convertWrapMode(attr->wrapMode_u,document); 359 texture->setWrap(osg::Texture2D::WRAP_S,wrap_s); 360 361 osg::Texture2D::WrapMode wrap_t = convertWrapMode(attr->wrapMode_v,document); 362 texture->setWrap(osg::Texture2D::WRAP_T,wrap_t); 363 364 // Min filter 365 switch (attr->minFilterMode) 366 { 367 case AttrData::MIN_FILTER_POINT: 368 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); 369 break; 370 case AttrData::MIN_FILTER_BILINEAR: 371 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); 372 break; 373 case AttrData::MIN_FILTER_MIPMAP_POINT: 374 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_NEAREST); 375 break; 376 case AttrData::MIN_FILTER_MIPMAP_LINEAR: 377 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_LINEAR); 378 break; 379 case AttrData::MIN_FILTER_MIPMAP_BILINEAR: 380 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST); 381 break; 382 case AttrData::MIN_FILTER_MIPMAP_TRILINEAR: 383 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR); 384 break; 385 case AttrData::MIN_FILTER_BICUBIC: 386 case AttrData::MIN_FILTER_BILINEAR_GEQUAL: 387 case AttrData::MIN_FILTER_BILINEAR_LEQUAL: 388 case AttrData::MIN_FILTER_BICUBIC_GEQUAL: 389 case AttrData::MIN_FILTER_BICUBIC_LEQUAL: 390 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST); 391 break; 392 default: 393 texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR); 394 break; 395 } 396 397 // Mag filter 398 switch (attr->magFilterMode) 399 { 400 case AttrData::MAG_FILTER_POINT: 401 texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); 402 break; 403 case AttrData::MAG_FILTER_BILINEAR: 404 case AttrData::MAG_FILTER_BILINEAR_GEQUAL: 405 case AttrData::MAG_FILTER_BILINEAR_LEQUAL: 406 case AttrData::MAG_FILTER_SHARPEN: 407 case AttrData::MAG_FILTER_BICUBIC: 408 case AttrData::MAG_FILTER_BICUBIC_GEQUAL: 409 case AttrData::MAG_FILTER_BICUBIC_LEQUAL: 410 case AttrData::MAG_FILTER_ADD_DETAIL: 411 case AttrData::MAG_FILTER_MODULATE_DETAIL: 412 texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); 413 break; 414 } 415 416 // Internal mode 417 switch(attr->intFormat) 418 { 419 case AttrData::INTERNAL_FORMAT_TX_I_12A_4: 420 texture->setInternalFormat(GL_LUMINANCE12_ALPHA4); 421 break; 422 case AttrData::INTERNAL_FORMAT_TX_IA_8: 423 texture->setInternalFormat(GL_LUMINANCE_ALPHA); 424 break; 425 case AttrData::INTERNAL_FORMAT_TX_RGB_5: 426 texture->setInternalFormat(GL_RGB5); 427 break; 428 case AttrData::INTERNAL_FORMAT_TX_RGBA_4: 429 texture->setInternalFormat(GL_RGBA4); 430 break; 431 case AttrData::INTERNAL_FORMAT_TX_IA_12: 432 texture->setInternalFormat(GL_LUMINANCE12_ALPHA12); 433 break; 434 case AttrData::INTERNAL_FORMAT_TX_RGBA_8: 435 texture->setInternalFormat(GL_RGBA8); 436 break; 437 case AttrData::INTERNAL_FORMAT_TX_RGBA_12: 438 texture->setInternalFormat(GL_RGBA12); 439 break; 440 case AttrData::INTERNAL_FORMAT_TX_I_16: 441 texture->setInternalFormat(GL_INTENSITY16); 442 break; 443 case AttrData::INTERNAL_FORMAT_TX_RGB_12: 444 texture->setInternalFormat(GL_RGB12); 445 break; 446 case AttrData::INTERNAL_FORMAT_DEFAULT: 447 default: 448 // Do nothing, just use the image data format 449 break; 450 } 451 452 osg::TexEnv* texenv = new osg::TexEnv; 453 switch (attr->texEnvMode) 454 { 455 case AttrData::TEXENV_MODULATE: 456 texenv->setMode(osg::TexEnv::MODULATE); 457 break; 458 case AttrData::TEXENV_BLEND: 459 texenv->setMode(osg::TexEnv::BLEND); 460 break; 461 case AttrData::TEXENV_DECAL: 462 texenv->setMode(osg::TexEnv::DECAL); 463 break; 464 case AttrData::TEXENV_COLOR: 465 texenv->setMode(osg::TexEnv::REPLACE); 466 break; 467 case AttrData::TEXENV_ADD: 468 texenv->setMode(osg::TexEnv::ADD); 469 break; 470 } 471 stateset->setTextureAttribute(0, texenv); 472 } 473 474 return stateset; 475 } 476 readRecord(RecordInputStream & in,Document & document)477 virtual void readRecord(RecordInputStream& in, Document& document) 478 { 479 if (document.getTexturePoolParent()) 480 // Using parent's texture pool -- ignore this record. 481 return; 482 483 int maxLength = (document.version() < VERSION_14) ? 80 : 200; 484 std::string filename = in.readString(maxLength); 485 int32 index = in.readInt32(-1); 486 /*int32 x =*/ in.readInt32(); 487 /*int32 y =*/ in.readInt32(); 488 489 // Need full path for unique key in local texture cache. 490 std::string pathname = osgDB::findDataFile(filename,document.getOptions()); 491 if (pathname.empty()) 492 { 493 OSG_WARN << "Can't find texture (" << index << ") " << filename << std::endl; 494 return; 495 } 496 497 // Is texture in local cache? 498 osg::ref_ptr<osg::StateSet> stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname); 499 500 // Read file if not in cache. 501 if (!stateset.valid()) 502 { 503 stateset = readTexture(pathname,document); 504 505 // Add to texture cache. 506 flt::Registry::instance()->addTextureToLocalCache(pathname,stateset.get()); 507 } 508 509 // Add to texture pool. 510 TexturePool* tp = document.getOrCreateTexturePool(); 511 (*tp)[index] = stateset; 512 } 513 }; 514 515 REGISTER_FLTRECORD(TexturePalette, TEXTURE_PALETTE_OP) 516 517 518 519 class EyepointAndTrackplanePalette : public Record 520 { 521 public: 522 EyepointAndTrackplanePalette()523 EyepointAndTrackplanePalette() {} 524 525 META_Record(EyepointAndTrackplanePalette) 526 527 protected: 528 ~EyepointAndTrackplanePalette()529 virtual ~EyepointAndTrackplanePalette() {} 530 readRecord(RecordInputStream &,Document &)531 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) {} 532 }; 533 534 REGISTER_FLTRECORD(EyepointAndTrackplanePalette, EYEPOINT_AND_TRACKPLANE_PALETTE_OP) 535 536 537 538 class LinkagePalette : public Record 539 { 540 public: 541 LinkagePalette()542 LinkagePalette() {} 543 544 META_Record(LinkagePalette) 545 546 protected: 547 ~LinkagePalette()548 virtual ~LinkagePalette() {} 549 readRecord(RecordInputStream &,Document &)550 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) {} 551 }; 552 553 REGISTER_FLTRECORD(LinkagePalette, LINKAGE_PALETTE_OP) 554 555 556 557 class SoundPalette : public Record 558 { 559 public: 560 SoundPalette()561 SoundPalette() {} 562 563 META_Record(SoundPalette) 564 565 protected: 566 ~SoundPalette()567 virtual ~SoundPalette() {} 568 readRecord(RecordInputStream &,Document &)569 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) {} 570 }; 571 572 REGISTER_FLTRECORD(SoundPalette, SOUND_PALETTE_OP) 573 574 575 576 class LightSourcePalette : public Record 577 { 578 public: 579 LightSourcePalette()580 LightSourcePalette() {} 581 582 META_Record(LightSourcePalette) 583 584 enum LightType 585 { 586 INFINITE_LIGHT = 0, 587 LOCAL_LIGHT = 1, 588 SPOT_LIGHT = 2 589 }; 590 591 protected: 592 ~LightSourcePalette()593 virtual ~LightSourcePalette() {} 594 readRecord(RecordInputStream & in,Document & document)595 virtual void readRecord(RecordInputStream& in, Document& document) 596 { 597 if (document.getLightSourcePoolParent()) 598 // Using parent's texture pool -- ignore this record. 599 return; 600 601 int32 index = in.readInt32(-1); 602 in.forward(2*4); 603 std::string name = in.readString(20); 604 in.forward(4); 605 osg::Vec4f ambient = in.readVec4f(); 606 osg::Vec4f diffuse = in.readVec4f(); 607 osg::Vec4f specular = in.readVec4f(); 608 int32 type = in.readInt32(); 609 in.forward(4*10); 610 float32 spotExponent = in.readFloat32(); 611 float32 spotCutoff = in.readFloat32(); 612 /*float32 yaw =*/ in.readFloat32(); 613 /*float32 pitch =*/ in.readFloat32(); 614 float32 constantAttenuation = in.readFloat32(); 615 float32 linearAttenuation = in.readFloat32(); 616 float32 quadraticAttenuation = in.readFloat32(); 617 /*int32 active =*/ in.readInt32(); 618 619 osg::ref_ptr<osg::Light> light = new osg::Light; 620 light->setAmbient(ambient); 621 light->setDiffuse(diffuse); 622 light->setSpecular(specular); 623 624 switch (type) 625 { 626 case INFINITE_LIGHT: 627 light->setPosition(osg::Vec4(0.0f,0.0f,1.0f,0.0f)); 628 break; 629 case LOCAL_LIGHT: 630 light->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); 631 light->setConstantAttenuation(constantAttenuation); 632 light->setLinearAttenuation(linearAttenuation); 633 light->setQuadraticAttenuation(quadraticAttenuation); 634 break; 635 case SPOT_LIGHT: 636 light->setPosition(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); 637 light->setDirection(osg::Vec3(0.0f,1.0f,0.0f)); 638 light->setConstantAttenuation(constantAttenuation); 639 light->setLinearAttenuation(linearAttenuation); 640 light->setQuadraticAttenuation(quadraticAttenuation); 641 light->setSpotExponent(spotExponent); 642 light->setSpotCutoff(spotCutoff); 643 break; 644 } 645 646 // Add to pool 647 LightSourcePool* pool = document.getOrCreateLightSourcePool(); 648 (*pool)[index] = light.get(); 649 } 650 }; 651 652 REGISTER_FLTRECORD(LightSourcePalette, LIGHT_SOURCE_PALETTE_OP) 653 654 655 656 class LightPointAppearancePalette : public Record 657 { 658 public: 659 LightPointAppearancePalette()660 LightPointAppearancePalette() {} 661 662 META_Record(LightPointAppearancePalette) 663 664 protected: 665 ~LightPointAppearancePalette()666 virtual ~LightPointAppearancePalette() {} 667 readRecord(RecordInputStream & in,Document & document)668 virtual void readRecord(RecordInputStream& in, Document& document) 669 { 670 if (document.getLightPointAppearancePoolParent()) 671 // Using parent's light point appearance pool -- ignore this record. 672 return; 673 674 osg::ref_ptr<LPAppearance> appearance = new LPAppearance; 675 676 in.forward(4); 677 appearance->name = in.readString(256); 678 appearance->index = in.readInt32(-1); 679 appearance->materialCode = in.readInt16(); 680 appearance->featureID = in.readInt16(); 681 682 int32 backColorIndex = in.readInt32(); 683 appearance->backColor = document.getColorPool() ? 684 document.getColorPool()->getColor(backColorIndex) : 685 osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f); 686 687 appearance->displayMode = in.readInt32(); 688 appearance->intensityFront = in.readFloat32(); 689 appearance->intensityBack = in.readFloat32(); 690 appearance->minDefocus = in.readFloat32(); 691 appearance->maxDefocus = in.readFloat32(); 692 appearance->fadingMode = in.readInt32(); 693 appearance->fogPunchMode = in.readInt32(); 694 appearance->directionalMode = in.readInt32(); 695 appearance->rangeMode = in.readInt32(); 696 appearance->minPixelSize = in.readFloat32(); 697 appearance->maxPixelSize = in.readFloat32(); 698 appearance->actualPixelSize = in.readFloat32(); 699 appearance->transparentFalloffPixelSize = in.readFloat32(); 700 appearance->transparentFalloffExponent = in.readFloat32(); 701 appearance->transparentFalloffScalar = in.readFloat32(); 702 appearance->transparentFalloffClamp = in.readFloat32(); 703 appearance->fogScalar = in.readFloat32(); 704 appearance->fogIntensity = in.readFloat32(); 705 appearance->sizeDifferenceThreshold = in.readFloat32(); 706 appearance->directionality = in.readInt32(); 707 appearance->horizontalLobeAngle = in.readFloat32(); 708 appearance->verticalLobeAngle = in.readFloat32(); 709 appearance->lobeRollAngle = in.readFloat32(); 710 appearance->directionalFalloffExponent = in.readFloat32(); 711 appearance->directionalAmbientIntensity = in.readFloat32(); 712 appearance->significance = in.readFloat32(); 713 appearance->flags = in.readUInt32(); 714 appearance->visibilityRange = in.readFloat32(); 715 appearance->fadeRangeRatio = in.readFloat32(); 716 appearance->fadeInDuration = in.readFloat32(); 717 appearance->fadeOutDuration = in.readFloat32(); 718 appearance->LODRangeRatio = in.readFloat32(); 719 appearance->LODScale = in.readFloat32(); 720 721 if(document.version() > VERSION_15_8) 722 appearance->texturePatternIndex = in.readInt16(-1); 723 else 724 appearance->texturePatternIndex = -1; 725 726 // The final short is reserved; don't bother reading it. 727 728 // Add to pool 729 LightPointAppearancePool* lpaPool = document.getOrCreateLightPointAppearancePool(); 730 (*lpaPool)[appearance->index] = appearance.get(); 731 } 732 733 }; 734 735 REGISTER_FLTRECORD(LightPointAppearancePalette, LIGHT_POINT_APPEARANCE_PALETTE_OP) 736 737 738 739 class LightPointAnimationPalette : public Record 740 { 741 public: 742 LightPointAnimationPalette()743 LightPointAnimationPalette() {} 744 745 META_Record(LightPointAnimationPalette) 746 747 protected: 748 ~LightPointAnimationPalette()749 virtual ~LightPointAnimationPalette() {} 750 readRecord(RecordInputStream & in,Document & document)751 virtual void readRecord(RecordInputStream& in, Document& document) 752 { 753 if (document.getLightPointAnimationPoolParent()) 754 // Using parent's light point animation pool -- ignore this record. 755 return; 756 757 osg::ref_ptr<LPAnimation> animation = new LPAnimation; 758 759 in.forward(4); 760 animation->name = in.readString(256); 761 animation->index = in.readInt32(-1); 762 // Rotating or strobe 763 animation->animationPeriod = in.readFloat32(); 764 animation->animationPhaseDelay = in.readFloat32(); 765 animation->animationEnabledPeriod = in.readFloat32(); 766 animation->axisOfRotation = in.readVec3f(); 767 animation->flags = in.readUInt32(); 768 animation->animationType = in.readInt32(); 769 770 // Morse code 771 animation->morseCodeTiming = in.readInt32(); 772 animation->wordRate = in.readInt32(); 773 animation->characterRate = in.readInt32(); 774 animation->morseCodeString = in.readString(1024); 775 776 // Flashing sequence 777 int32 numberOfSequences = in.readInt32(); 778 for (int n=0; n<numberOfSequences; ++n) 779 { 780 LPAnimation::Pulse pulse; 781 pulse.state = in.readUInt32(); 782 pulse.duration = in.readFloat32(); 783 pulse.color = in.readColor32(); 784 785 animation->sequence.push_back(pulse); 786 } 787 788 // Add to pool 789 LightPointAnimationPool* lpaPool = document.getOrCreateLightPointAnimationPool(); 790 (*lpaPool)[animation->index] = animation.get(); 791 } 792 }; 793 794 REGISTER_FLTRECORD(LightPointAnimationPalette, LIGHT_POINT_ANIMATION_PALETTE_OP) 795 796 797 798 class LineStylePalette : public Record 799 { 800 public: 801 LineStylePalette()802 LineStylePalette() {} 803 804 META_Record(LineStylePalette) 805 806 protected: 807 ~LineStylePalette()808 virtual ~LineStylePalette() {} 809 readRecord(RecordInputStream &,Document &)810 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) 811 { 812 } 813 }; 814 815 REGISTER_FLTRECORD(LineStylePalette, LINE_STYLE_PALETTE_OP) 816 817 818 819 class TextureMappingPalette : public Record 820 { 821 public: 822 TextureMappingPalette()823 TextureMappingPalette() {} 824 825 META_Record(TextureMappingPalette) 826 827 protected: 828 ~TextureMappingPalette()829 virtual ~TextureMappingPalette() {} 830 readRecord(RecordInputStream &,Document &)831 virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/) 832 { 833 } 834 }; 835 836 REGISTER_FLTRECORD(TextureMappingPalette, TEXTURE_MAPPING_PALETTE_OP) 837 838 839 840 class ShaderPalette : public Record 841 { 842 public: 843 ShaderPalette()844 ShaderPalette() {} 845 846 META_Record(ShaderPalette) 847 848 enum ShaderType 849 { 850 CG=0, 851 CGFX=1, 852 GLSL=2 853 }; 854 855 protected: 856 ~ShaderPalette()857 virtual ~ShaderPalette() {} 858 readRecord(RecordInputStream & in,Document & document)859 virtual void readRecord(RecordInputStream& in, Document& document) 860 { 861 if (document.getShaderPoolParent()) 862 // Using parent's shader pool -- ignore this record. 863 return; 864 865 int32 index = in.readInt32(-1); 866 int32 type = in.readInt32(-1); 867 std::string name = in.readString(1024); 868 869 if (type == CG) 870 { 871 // CG support is currently not implemented. Just parse. 872 std::string vertexProgramFilename = in.readString(1024); 873 std::string fragmentProgramFilename = in.readString(1024); 874 /*int32 vertexProgramProfile =*/ in.readInt32(); 875 /*int32 fragmentProgramProfile =*/ in.readInt32(); 876 std::string vertexProgramEntry = in.readString(256); 877 std::string fragmentProgramEntry = in.readString(256); 878 } 879 else if (type == GLSL) 880 { 881 int32 vertexProgramFileCount(1); 882 int32 fragmentProgramFileCount(1); 883 884 if (document.version() >= VERSION_16_1) 885 { 886 // In 16.1, possibly multiple filenames for each vertex and fragment program. 887 vertexProgramFileCount = in.readInt32(); 888 fragmentProgramFileCount = in.readInt32(); 889 } 890 // else 16.0 891 // Technically, 16.0 didn't support GLSL, but this plugin 892 // supports it with a single vertex shader filename and a 893 // single fragment shader filename. 894 895 osg::Program* program = new osg::Program; 896 program->setName(name); 897 898 // Read vertex programs 899 int idx; 900 for( idx=0; idx<vertexProgramFileCount; idx++) 901 { 902 std::string vertexProgramFilename = in.readString(1024); 903 904 std::string vertexProgramFilePath = osgDB::findDataFile(vertexProgramFilename,document.getOptions()); 905 if (!vertexProgramFilePath.empty()) 906 { 907 osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, vertexProgramFilePath); 908 if (vertexShader) 909 program->addShader( vertexShader ); 910 } 911 } 912 913 // Read fragment programs 914 for( idx=0; idx<fragmentProgramFileCount; idx++) 915 { 916 std::string fragmentProgramFilename = in.readString(1024); 917 918 std::string fragmentProgramFilePath = osgDB::findDataFile(fragmentProgramFilename,document.getOptions()); 919 if (!fragmentProgramFilePath.empty()) 920 { 921 osg::ref_ptr<osg::Shader> fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, fragmentProgramFilePath); 922 if (fragmentShader) 923 program->addShader( fragmentShader ); 924 } 925 } 926 927 // Add to shader pool 928 ShaderPool* shaderPool = document.getOrCreateShaderPool(); 929 (*shaderPool)[index] = program; 930 } 931 } 932 }; 933 934 REGISTER_FLTRECORD(ShaderPalette, SHADER_PALETTE_OP) 935 936 937 } // end namespace 938 939 940