From Brede Johansen, new OpenFlight plugin!!!!!

By default the original flt plugin is still used, to select at runtime
the new plugin set the env OSG_OPEN_FLIGHT_PLUGIN=new
This commit is contained in:
Robert Osfield
2006-03-08 21:38:37 +00:00
parent 4fc4e60cc3
commit 3246dde716
41 changed files with 6475 additions and 2 deletions

View File

@@ -70,8 +70,9 @@ PLUGIN_DIRS = \
directx \
dw \
dxf \
ESRIShape \
ESRIShape \
flt \
OpenFlight \
hdr \
ive \
lib3ds \
@@ -80,7 +81,7 @@ PLUGIN_DIRS = \
lws \
md2 \
net \
normals \
normals \
obj \
osg \
osga \

View File

@@ -2763,6 +2763,30 @@ Package=<4>
###############################################################################
Project: "osgPlugin OpenFlight"=.\osgPlugins\OpenFlight\OpenFlight.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name Core osg
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgDB
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgUtil
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgSim
End Project Dependency
}}}
###############################################################################
Project: "osgPlugin freetype"=.\osgPlugins\freetype\freetype.dsp - Package Owner=<4>
Package=<5>

View File

@@ -0,0 +1,222 @@
# Microsoft Developer Studio Project File - Name="osgPlugin OpenFlight" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=osgPlugin OpenFlight - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "OpenFlight.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "OpenFlight.mak" CFG="osgPlugin OpenFlight - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "osgPlugin OpenFlight - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "osgPlugin OpenFlight - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "osgPlugin OpenFlight - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FLT_LIBRARY" /YX /FD /Zm200 /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x414 /d "NDEBUG"
# ADD RSC /l 0x417 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 OpenThreadsWin32.lib /nologo /dll /pdb:none /machine:I386 /out:"../../../bin/osgdb_OpenFlight.dll" /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib"
!ELSEIF "$(CFG)" == "osgPlugin OpenFlight - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../../lib"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /vmg /GR /GX /Zi /Od /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FLT_LIBRARY" /D "WIN32" /D "_DEBUG" /YX /FD /GZ /Zm200 /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x414 /d "_DEBUG"
# ADD RSC /l 0x417 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenThreadsWin32d.lib /nologo /dll /pdb:"../../../bin/osgdb_OpenFlightd.pdb" /debug /machine:I386 /out:"../../../bin/osgdb_OpenFlightd.dll" /pdbtype:sept /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib"
# SUBTRACT LINK32 /pdb:none /incremental:no
!ENDIF
# Begin Target
# Name "osgPlugin OpenFlight - Win32 Release"
# Name "osgPlugin OpenFlight - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\AncillaryRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\AttrData.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\ControlRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\DataInputStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Document.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\GeometryRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\LightPointRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\PaletteRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Pools.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\PrimaryRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\ReaderWriterATTR.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\ReaderWriterFLT.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Record.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\RecordInputStream.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Registry.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\ReservedRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\RoadRecords.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Vertex.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\VertexRecords.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;"
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\AttrData.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\DataInputStream.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Document.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\opcodes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Pools.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Record.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\RecordInputStream.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Registry.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\types.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\OpenFlight\Vertex.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -139,6 +139,10 @@ SOURCE=..\..\src\osgSim\OverlayNode.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgSim\OpenFlightOptimizer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgSim\ScalarBar.cpp
# End Source File
# Begin Source File
@@ -219,6 +223,10 @@ SOURCE=..\..\include\osgSim\OverlayNode
# End Source File
# Begin Source File
SOURCE=..\..\include\osgSim\OpenFlightOptimizer
# End Source File
# Begin Source File
SOURCE=..\..\include\osgSim\ScalarBar
# End Source File
# Begin Source File

View File

@@ -139,6 +139,10 @@ SOURCE=..\..\..\src\osgWrappers\osgSim\LightPointSystem.cpp
SOURCE=..\..\..\src\osgWrappers\osgSim\MultiSwitch.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgWrappers\osgSim\OpenFlightOptimizer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgWrappers\osgSim\OverlayNode.cpp
# End Source File

View File

@@ -0,0 +1,114 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef OSGSIM_OPENFLIGHTOPTIMIZER
#define OSGSIM_OPENFLIGHTOPTIMIZER
#include <osg/NodeVisitor>
#include <osg/Group>
#include <osg/Geometry>
#include <osgSim/Export>
namespace osgFlightUtil {
/** Flight optimizer
*/
class OSGSIM_EXPORT Optimizer
{
public:
Optimizer() {}
virtual ~Optimizer() {}
enum OptimizationOptions
{
TESSELATE_POLYGON = 0x001,
MERGE_GEODES = 0x002,
MAKE_LIT = 0x004,
DEFAULT_OPTIMIZATIONS = TESSELATE_POLYGON | MERGE_GEODES,
ALL_OPTIMIZATIONS = TESSELATE_POLYGON | MERGE_GEODES
};
/** Traverse the node and its subgraph with a series of optimization
* visitors, specified by the OptimizationOptions.*/
void optimize(osg::Node* node);
/** Traverse the node and its subgraph with a series of optimization
* visitors, specified by the OptimizationOptions.*/
virtual void optimize(osg::Node* node, unsigned int options);
protected:
public:
class TesselateVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
TesselateVisitor() :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Geode& geode);
protected:
bool hasPolygons(osg::Geometry& geometry);
};
class MakeLitVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
MakeLitVisitor() :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Geode& geode);
};
/** Combine geodes
*/
class MergeGeodesVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
MergeGeodesVisitor() :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Group& group);
void mergeGeodes(osg::Group& group);
protected:
bool mergeGeode(osg::Geode& lhs, osg::Geode& rhs);
};
};
} // end namespace
#endif

View File

@@ -140,6 +140,15 @@ Registry::Registry()
initFilePathLists();
// register file extension alias.
const char* flt_str = getenv("OSG_OPEN_FLIGHT_PLUGIN");
if (flt_str)
{
if (strcmp(flt_str, "new")==0)
{
addFileExtensionAlias("flt", "OpenFlight");
}
}
addFileExtensionAlias("sgi", "rgb");
addFileExtensionAlias("rgba", "rgb");
addFileExtensionAlias("int", "rgb");

View File

@@ -0,0 +1,269 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
/** Comment -
*/
class Comment : public Record
{
public:
Comment() {}
META_Record(Comment)
protected:
virtual ~Comment() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::streamsize size = in.getRecordSize();
std::string comment = in.readString(size-4);
if (_parent.valid())
_parent->setComment(comment);
}
};
RegisterRecordProxy<Comment> g_Comment(COMMENT_OP);
/** LongID -
*/
class LongID : public Record
{
public:
LongID() {}
META_Record(LongID)
protected:
virtual ~LongID() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::streamsize size = in.getRecordSize();
std::string id = in.readString(size-4);
if (_parent.valid())
_parent->setID(id);
}
};
RegisterRecordProxy<LongID> g_LongID(LONG_ID_OP);
/** Matrix -
*/
class Matrix : public Record
{
public:
Matrix() {}
META_Record(Matrix)
protected:
virtual ~Matrix() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
osg::Matrix matrix;
for (int i=0; i<4; ++i)
{
for (int j=0; j<4; ++j)
{
matrix(i,j) = in.readFloat32();
}
}
// scale position.
osg::Vec3 pos = matrix.getTrans();
matrix *= osg::Matrix::translate(-pos);
pos *= (float)document.unitScale();
matrix *= osg::Matrix::translate(pos);
if (_parent.valid())
_parent->setMatrix(matrix);
}
};
RegisterRecordProxy<Matrix> g_Matrix(MATRIX_OP);
/** Multitexture -
*/
class Multitexture : public Record
{
public:
Multitexture() {}
META_Record(Multitexture)
protected:
virtual ~Multitexture() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
uint32 mask = in.readUInt32();
for (int layer=1; layer<8; layer++)
{
uint32 layerBit = 0x80000000u >> (layer-1);
if (mask & layerBit)
{
int16 textureIndex = in.readInt16();
int16 effectIndex = in.readInt16();
int16 mappingIndex = in.readInt16();
uint16 data= in.readUInt16();
osg::ref_ptr<osg::StateSet> texturePoolStateset = document.getOrCreateTexturePool()->get(textureIndex);
if (stateset.valid() && texturePoolStateset.valid())
{
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>(texturePoolStateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
if (texture)
stateset->setTextureAttributeAndModes(layer,texture,osg::StateAttribute::ON);
}
}
}
if (_parent.valid())
_parent->setMultitexture(*stateset);
}
};
RegisterRecordProxy<Multitexture> g_Multitexture(MULTITEXTURE_OP);
/** UVList - Texture coordinates used with multitexture.
UVList is an ancillary to VertexList.
*/
class UVList : public Record
{
public:
UVList() {}
META_Record(UVList)
protected:
virtual ~UVList() {}
// count number of 1's in mask.
int bitCount(uint32 mask)
{
int count = 0;
while (mask)
{
if (mask & 0x0001)
++count;
mask >>= 1;
}
return count;
}
virtual void readRecord(RecordInputStream& in, Document& document)
{
uint32 mask = in.readUInt32(0);
int numLayers = bitCount(mask);
int numVertices = (in.getRecordSize()-8) / (8 * numLayers);
for (int n=0; n < numVertices; ++n)
{
for (unsigned int layer=1; layer<8; layer++)
{
uint32 layerBit = 0x80000000u >> (layer-1);
if (mask & layerBit)
{
float32 u = in.readFloat32();
float32 v = in.readFloat32();
// Add texture coodinates to geometry.
if (_parent.valid())
_parent->addVertexUV(layer,osg::Vec2(u,v));
}
}
}
}
};
RegisterRecordProxy<UVList> g_UVList(UV_LIST_OP);
/** Replicate -
*/
class Replicate : public Record
{
public:
Replicate() {}
META_Record(Replicate)
protected:
virtual ~Replicate() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int16 replicate = in.readInt16();
if (_parent.valid())
_parent->setNumberOfReplications((int)replicate);
}
};
RegisterRecordProxy<Replicate> g_Replicate(REPLICATE_OP);
// Prevent "unknown record" message for the following ancillary records:
RegisterRecordProxy<DummyRecord> g_OldTranslate(OLD_TRANSLATE2_OP);
RegisterRecordProxy<DummyRecord> g_OldRotateAboutPoint(OLD_ROTATE_ABOUT_POINT_OP);
RegisterRecordProxy<DummyRecord> g_OldRotateAboutEdge(OLD_ROTATE_ABOUT_EDGE_OP);
RegisterRecordProxy<DummyRecord> g_OldScale(OLD_SCALE_OP);
RegisterRecordProxy<DummyRecord> g_OldTranslate2(OLD_TRANSLATE_OP);
RegisterRecordProxy<DummyRecord> g_OldNonuniformScale(OLD_NONUNIFORM_SCALE_OP);
RegisterRecordProxy<DummyRecord> g_OldRotateAboutPoint2(OLD_ROTATE_ABOUT_POINT2_OP);
RegisterRecordProxy<DummyRecord> g_OldRotateScaleToPoint(OLD_ROTATE_SCALE_TO_POINT_OP);
RegisterRecordProxy<DummyRecord> g_OldPutTransform(OLD_PUT_TRANSFORM_OP);
RegisterRecordProxy<DummyRecord> g_OldBoundingBox(OLD_BOUNDING_BOX_OP);
RegisterRecordProxy<DummyRecord> g_IndexedString(INDEXED_STRING_OP);
RegisterRecordProxy<DummyRecord> g_RoadZone(ROAD_ZONE_OP);
RegisterRecordProxy<DummyRecord> g_RotateAboutEdge(ROTATE_ABOUT_EDGE_OP);
RegisterRecordProxy<DummyRecord> g_Translate(TRANSLATE_OP);
RegisterRecordProxy<DummyRecord> g_Scale(NONUNIFORM_SCALE_OP);
RegisterRecordProxy<DummyRecord> g_RotateAboutPoint(ROTATE_ABOUT_POINT_OP);
RegisterRecordProxy<DummyRecord> g_RotateScaleToPoint(ROTATE_SCALE_TO_POINT_OP);
RegisterRecordProxy<DummyRecord> g_PutTransform(PUT_TRANSFORM_OP);
RegisterRecordProxy<DummyRecord> g_GeneralMatrix(GENERAL_MATRIX_OP);
RegisterRecordProxy<DummyRecord> g_Vector(VECTOR_OP);
RegisterRecordProxy<DummyRecord> g_BoundingBox(BOUNDING_BOX_OP);
RegisterRecordProxy<DummyRecord> g_BoundingSphere(BOUNDING_SPHERE_OP);
RegisterRecordProxy<DummyRecord> g_BoundingCylinder(BOUNDING_CYLINDER_OP);
RegisterRecordProxy<DummyRecord> g_BoundingConvexHull(BOUNDING_CONVEX_HULL_OP);
RegisterRecordProxy<DummyRecord> g_BoundingHistogram(BOUNDING_HISTOGRAM);
RegisterRecordProxy<DummyRecord> g_BoundingVolumeCenter(BOUNDING_VOLUME_CENTER_OP);
RegisterRecordProxy<DummyRecord> g_BoundingVolumeOrientation(BOUNDING_VOLUME_ORIENTATION_OP);
RegisterRecordProxy<DummyRecord> g_HistogramBoundingVolume(HISTOGRAM_BOUNDING_VOLUME_OP);
} // end namespace

View File

@@ -0,0 +1,76 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "AttrData.h"
using namespace flt;
AttrData::AttrData() :
texels_u(0),
textel_v(0),
direction_u(0),
direction_v(0),
x_up(0),
y_up(0),
fileFormat(-1), // -1 Not used
minFilterMode(MIN_FILTER_NONE),
magFilterMode(MAG_FILTER_POINT),
wrapMode(WRAP_REPEAT),
wrapMode_u(WRAP_REPEAT),
wrapMode_v(WRAP_REPEAT),
modifyFlag(0),
pivot_x(0),
pivot_y(0),
texEnvMode(TEXENV_MODULATE),
intensityAsAlpha(0),
size_u(0),
size_v(0),
originCode(0),
kernelVersion(0),
intFormat(0), // 0 - Default
extFormat(0), // 0 - Default
useMips(0),
// float32 _mips[8]),
useLodScale(0),
// float32 lod0),
// float32 scale0),
// ...
// float32 lod7),
// float32 scale7),
clamp(0),
magFilterAlpha(2), // 2 = None
magFilterColor(2), // 2 = None
lambertMeridian(0),
lambertUpperLat(0),
lambertlowerLat(0),
useDetail(0),
txDetail_j(0),
txDetail_k(0),
txDetail_m(0),
txDetail_n(0),
txDetail_s(0),
useTile(0),
txTile_ll_u(0),
txTile_ll_v(0),
txTile_ur_u(0),
txTile_ur_v(0),
projection(PROJECTION_UNDEFINED),
earthModel(DATUM_WGS84),
utmZone(0),
imageOrigin(0),
geoUnits(0),
hemisphere(1),
comments(""),
attrVersion(0),
controlPoints(0)
// TODO:
{}
AttrData::AttrData(const AttrData& attr, const osg::CopyOp& copyop) :
osg::Object(attr,copyop)
{}

View File

@@ -0,0 +1,310 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_ATTRDATA_H
#define FLT_ATTRDATA_H
#include <string>
#include <osg/Object>
#include "types.h"
namespace flt {
class AttrData : public osg::Object
{
public :
AttrData();
AttrData(const AttrData& attr, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
META_Object(flt,AttrData);
enum MinFilterMode {
MIN_FILTER_POINT = 0,
MIN_FILTER_BILINEAR = 1,
MIN_FILTER_MIPMAP = 2, // (Obsolete)
MIN_FILTER_MIPMAP_POINT = 3,
MIN_FILTER_MIPMAP_LINEAR = 4,
MIN_FILTER_MIPMAP_BILINEAR = 5,
MIN_FILTER_MIPMAP_TRILINEAR = 6,
MIN_FILTER_NONE = 7,
MIN_FILTER_BICUBIC = 8,
MIN_FILTER_BILINEAR_GEQUAL = 9,
MIN_FILTER_BILINEAR_LEQUAL = 10,
MIN_FILTER_BICUBIC_GEQUAL = 11,
MIN_FILTER_BICUBIC_LEQUAL = 12
};
enum MagFilterMode {
MAG_FILTER_POINT = 0,
MAG_FILTER_BILINEAR = 1,
MAG_FILTER_NONE = 2,
MAG_FILTER_BICUBIC = 3,
MAG_FILTER_SHARPEN = 4,
MAG_FILTER_ADD_DETAIL = 5,
MAG_FILTER_MODULATE_DETAIL = 6,
MAG_FILTER_BILINEAR_GEQUAL = 7,
MAG_FILTER_BILINEAR_LEQUAL = 8,
MAG_FILTER_BICUBIC_GEQUAL = 9,
MAG_FILTER_BICUBIC_LEQUAL = 10
};
enum WrapMode {
WRAP_REPEAT = 0,
WRAP_CLAMP = 1
};
enum TexEnvMode {
TEXENV_MODULATE = 0,
TEXENV_BLEND = 1,
TEXENV_DECAL = 2,
TEXENV_COLOR = 3
};
enum Projection {
PROJECTION_FLAT = 0,
PROJECTION_LAMBERT_CONIC = 3,
PROJECTION_UTM = 4,
PROJECTION_UNDEFINED = 7
};
enum Datum {
DATUM_WGS84 = 0,
DATUM_WGS72 = 1,
DATUM_BESSEL = 2,
DATUM_CLARK_1866 = 3,
DATUM_NAD27 = 4
};
int32 texels_u; // Number of texels in u direction
int32 textel_v; // Number of texels in v direction
int32 direction_u; // Real world size u direction
int32 direction_v; // Real world size v direction
int32 x_up; // x component of up vector
int32 y_up; // y component of up vector
int32 fileFormat; // File format type
// -1 Not used
// 0 AT&T image 8 pattern
// 1 AT&T image 8 template
// 2 SGI intensity modulation
// 3 SGI intensity w/ alpha
// 4 SGI RGB
// 5 SGI RGB w/ alpha
int32 minFilterMode; // Minification filter type
// 0 - TX_POINT
// 1 - TX_BILINEAR
// 2 - TX_MIPMAP (Obsolete)
// 3 - TX_MIPMAP_POINT
// 4 - TX_MIPMAP_LINEAR
// 5 - TX_MIPMAP_BILINEAR
// 6 - TX_MIPMAP_TRILINEAR
// 7 - None
// 8 - TX_BICUBIC
// 9 - TX_BILINEAR_GEQUAL
// 10 - TX_BILINEAR_LEQUAL
// 11 - TX_BICUBIC_GEQUAL
// 12 - TX_BICUBIC_LEQUAL
int32 magFilterMode; // Magnification filter type
// 0 - TX_POINT
// 1 - TX_BILINEAR
// 2 - None
// 3 - TX_BICUBIC
// 4 - TX_SHARPEN
// 5 - TX_ADD_DETAIL
// 6 - TX_MODULATE_DETAIL
// 7 - TX_BILINEAR_GEQUAL
// 8 - TX_BILINEAR_LEQUAL
// 9 - TX_BICUBIC_GEQUAL
// 10 - TX_BICUBIC_LEQUAL
int32 wrapMode; // Repetition type
// 0 - TX_REPEAT
// 1 - TX_CLAMP
// 2 - (Obsolete)
int32 wrapMode_u; // Repetition type in u direction (see above)
int32 wrapMode_v; // Repetition type in v direction (see above)
int32 modifyFlag; // Modify flag (for internal use)
int32 pivot_x; // x pivot point for rotating textures
int32 pivot_y; // y pivot point for rotating textures
// --------------
// v11 ends here
// --------------
int32 texEnvMode; // Environment type
// 0 - TV_MODULATE
// 1 - TV_BLEND
// 2 - TV_DECAL
// 3 - TV_COLOR
int32 intensityAsAlpha; // TRUE if intensity pattern to be loaded in alpha with white in color
// int32 spare1[8]; // 8 words of spare
float64 size_u; // Real world size u for floating point databases
float64 size_v; // Real world size v for floating point databases
int32 originCode; // Code for origin of imported texture
int32 kernelVersion; // Kernel version number
int32 intFormat; // Internal format type
// 0 - Default
// 1 - TX_I_12A_4
// 2 - TX_IA_8
// 3 - TX_RGB_5
// 4 - TX_RGBA_4
// 5 - TX_IA_12
// 6 - TX_RGBA_8
// 7 - TX_RGBA_12
// 8 - TX_I_16 (shadow mode only)
// 9 - TX_RGB_12
int32 extFormat; // External format type
// 0 - Default
// 1 - TX_PACK_8
// 2 - TX_PACK_16
int32 useMips; // TRUE if using following 8 floats for MIPMAP kernel
float32 _mips[8]; // 8 floats for kernel of separable symmetric filter
int32 useLodScale; // Boolean if TRUE send:
float32 lod0; // LOD0 for TX_CONTROL_POINT
float32 scale0; // SCALE0 for TX_CONTROL_POINT
float32 lod1; // LOD1 for TX_CONTROL_POINT
float32 scale1; // SCALE1 for TX_CONTROL_POINT
float32 lod2; // LOD2 for TX_CONTROL_POINT
float32 scale2; // SCALE2 for TX_CONTROL_POINT
float32 lod3; // LOD3 for TX_CONTROL_POINT
float32 scale3; // SCALE3 for TX_CONTROL_POINT
float32 lod4; // LOD4 for TX_CONTROL_POINT
float32 scale4; // SCALE4 for TX_CONTROL_POINT
float32 lod5; // LOD5 for TX_CONTROL_POINT
float32 scale5; // SCALE5 for TX_CONTROL_POINT
float32 lod6; // LOD6 for TX_CONTROL_POINT
float32 scale6; // SCALE6 for TX_CONTROL_POINT
float32 lod7; // LOD7 for TX_CONTROL_POINT
float32 scale7; // SCALE7 for TX_CONTROL_POINT
float32 clamp; // Clamp
int32 magFilterAlpha; // magfilteralpha:
// 0 = TX_POINT
// 1 = TX_BILINEAR
// 2 = None
// 3 = TX_BICUBIC
// 4 = TX_SHARPEN
// 5 = TX_ADD_DETAIL
// 6 = TX_MODULATE_DETAIL
// 7 = TX_BILINEAR_GEQUAL
// 8 = TX_BILINEAR_LEQUAL
// 9 = TX_BICUBIC_GEQUAL
// 10 = TX_BIBICUBIC_LEQUAL
int32 magFilterColor; // magfiltercolor:
// 0 = TX_POINT
// 1 = TX_BILINEAR
// 2 = None
// 3 = TX_BICUBIC
// 4 = TX_SHARPEN
// 5 = TX_ADD_DETAIL
// 6 = TX_MODULATE_DETAIL
// 7 = TX_BILINEAR_GEQUAL
// 8 = TX_BILINEAR_LEQUAL
// 9 = TX_BICUBIC_GEQUAL
// 10 = TX_BIBICUBIC_LEQUAL
// float32 reserved1; // Reserved
// float32 reserved2[8]; // Reserved
float64 lambertMeridian; // Lambert conic projection central meridian
float64 lambertUpperLat; // Lambert conic projection upper latitude
float64 lambertlowerLat; // Lambert conic projection lower latitude
// float64 reserved3; // Reserved
// float32 spare2[5]; // Spare
int32 useDetail; // TRUE if using next 5 integers for detail texture
int32 txDetail_j; // J argument for TX_DETAIL
int32 txDetail_k; // K argument for TX_DETAIL
int32 txDetail_m; // M argument for TX_DETAIL
int32 txDetail_n; // N argument for TX_DETAIL
int32 txDetail_s; // Scramble argument for TX_DETAIL
int32 useTile; // TRUE if using next for floats for TX_TILE
float32 txTile_ll_u; // Lower-left u value for TX_TILE
float32 txTile_ll_v; // Lower-left v value for TX_TILE
float32 txTile_ur_u; // Upper-right u value for TX_TILE
float32 txTile_ur_v; // Upper-right v value for TX_TILE
int32 projection; // Projection
// 0 = Flat earth
// 3 = Lambert conic
// 4 = UTM
// 7 = Undefined projection
int32 earthModel; // Earth model
// 0 = WGS84
// 1 = WGS72
// 2 = Bessel
// 3 = Clark 1866
// 4 = NAD27
// int32 reserved4; // Reserved
int32 utmZone; // UTM zone
int32 imageOrigin; // Image origin
// 0 = Lower-left
// 1 = Upper-left
int32 geoUnits; // Geospecific points units
// 0 = Degrees
// 1 = Meters
// 2 = Pixels
// int32 reserved5; // Reserved
// int32 reserved6; // Reserved
int32 hemisphere; // Hemisphere for geospecific points units
// 0 = Southern
// 1 = Northern
// int32 reserved7; // Reserved
// int32 reserved8; // Reserved
// int32 spare3[149]; // Spare
// char comments[512]; // Comments
std::string comments;
// --------------
// v12 ends here
// --------------
// int32 reserved9[13]; // Reserved
int32 attrVersion; // Attribute file version number
int32 controlPoints; // Number of geospecific control points
// If the number of geospecific control points is > 0,
// the following fields are also in the attribute file:
int32 reserved10; // Reserved
#if 0
// For each geospecific control point:
{
float64 texel_u; // Texel u of geospecific control point
float64 texel_v; // Texel v of geospecific control point
float64 geoPoint[2]; // Real earth coordinate of geospecific control point
// (this value depends on the projection, earth model,
// and geospecific points units)
}
// ----------------
// v15.6 ends here
// ----------------
// After all geospecific control points are listed, the following subtexture
// information appears:
int32 subtextures; // Number of subtexture definitions contained in the
// texture attribute file
// If the number of subtexture definitions is >0,
// the following fields are repeated for each subtexture definition:
{
char name[32]; // name of subtexture definition
int32 left; // Coordinate of left edge of subtexture
// definition measured in texels.
int32 bottom; // Coordinate of bottom edge of subtexture
// definition measured in texels.
int32 right; // Coordinate of right edge of subtexture
// definition measured in texels.
int32 top; // Coordinate of top edge of subtexture
// definition measured in texels.
}
#endif
};
} // end namespace
#endif

View File

@@ -0,0 +1,210 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <cassert>
#include <osg/Geode>
#include <osg/Geometry>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
/** PushLevel
*/
class PushLevel : public Record
{
public:
PushLevel() {}
META_Record(PushLevel)
virtual void read(RecordInputStream& in, Document& document)
{
document.pushLevel();
}
protected:
virtual ~PushLevel() {}
};
RegisterRecordProxy<PushLevel> g_PushLevel(PUSH_LEVEL_OP);
/** PophLevel
*/
class PopLevel : public Record
{
public:
PopLevel() {}
META_Record(PopLevel)
virtual void read(RecordInputStream& in, Document& document)
{
document.popLevel();
}
protected:
virtual ~PopLevel() {}
};
RegisterRecordProxy<PopLevel> g_PopLevel(POP_LEVEL_OP);
/** PushSubface
*/
class PushSubface : public Record
{
public:
PushSubface() {}
META_Record(PushSubface)
virtual void read(RecordInputStream& in, Document& document)
{
document.pushSubface();
}
protected:
virtual ~PushSubface() {}
};
RegisterRecordProxy<PushSubface> g_PushSubface(PUSH_SUBFACE_OP);
/** PopSubface
*/
class PopSubface : public Record
{
public:
PopSubface() {}
META_Record(PopSubface)
virtual void read(RecordInputStream& in, Document& document)
{
document.popSubface();
}
protected:
virtual ~PopSubface() {}
};
RegisterRecordProxy<PopSubface> g_PopSubface(POP_SUBFACE_OP);
/** PushExtension
*/
class PushExtension : public Record
{
public:
PushExtension() {}
META_Record(PushExtension)
virtual void read(RecordInputStream& in, Document& document)
{
readRecord(in,document);
document.pushExtension();
}
protected:
virtual ~PushExtension() {}
};
RegisterRecordProxy<PushExtension> g_PushExtension(PUSH_EXTENSION_OP);
/** PopExtension
*/
class PopExtension : public Record
{
public:
PopExtension() {}
META_Record(PopExtension)
virtual void read(RecordInputStream& in, Document& document)
{
readRecord(in,document);
document.popExtension();
}
protected:
virtual ~PopExtension() {}
};
RegisterRecordProxy<PopExtension> g_PopExtension(POP_EXTENSION_OP);
/** PushAttribute - Reserved subtree
*/
class PushAttribute : public Record
{
public:
PushAttribute() {}
META_Record(PushAttribute)
virtual void read(RecordInputStream& in, Document& document)
{
readRecord(in,document);
// in().seekg(in.getEndOfRecord(), std::ios_base::beg);
// loop until PopAttribute
}
protected:
virtual ~PushAttribute() {}
};
RegisterRecordProxy<PushAttribute> g_PushAttribute(PUSH_ATTRIBUTE_OP);
/** PopAttribute
*/
class PopAttribute : public Record
{
public:
PopAttribute() {}
META_Record(PopAttribute)
virtual void read(RecordInputStream& in, Document& document)
{
readRecord(in,document);
}
protected:
virtual ~PopAttribute() {}
};
RegisterRecordProxy<PopAttribute> g_PopAttribute(POP_ATTRIBUTE_OP);
} // end namespace

View File

@@ -0,0 +1,210 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "DataInputStream.h"
#include <osg/Endian>
#include <osg/Notify>
#include <osgDB/ReadFile>
using namespace flt;
DataInputStream::DataInputStream(std::istream* istream):
_istream(istream)
{
_byteswap = osg::getCpuByteOrder() == osg::LittleEndian;
if (!istream)
throw std::string("DataInputStream::DataInputStream(): null pointer exception in argument.");
}
DataInputStream::~DataInputStream()
{
}
int8 DataInputStream::readInt8(int8 def) const
{
int8 d=def;
read((char*)&d, sizeof(int8));
return d;
}
uint8 DataInputStream::readUInt8(uint8 def) const
{
uint8 d=def;
read((char*)&d, sizeof(uint8));
return d;
}
int16 DataInputStream::readInt16(int16 def) const
{
int16 d=def;
read((char*)&d, sizeof(int16));
if (_byteswap && !_istream->fail())
osg::swapBytes2((char *)&d);
return d;
}
uint16 DataInputStream::readUInt16(uint16 def) const
{
uint16 d=def;
read((char*)&d, sizeof(uint16));
if (_byteswap && !_istream->fail())
osg::swapBytes2((char *)&d);
return d;
}
int32 DataInputStream::readInt32(int32 def) const
{
int32 d=def;
read((char*)&d, sizeof(int32));
if (_byteswap && !_istream->fail())
osg::swapBytes4((char *)&d);
return d;
}
uint32 DataInputStream::readUInt32(uint32 def) const
{
uint32 d=def;
read((char*)&d, sizeof(uint32));
if (_byteswap && !_istream->fail())
osg::swapBytes4((char *)&d);
return d;
}
float32 DataInputStream::readFloat32(float32 def) const
{
float32 d=def;
char buf[sizeof(float32)];
read(buf, sizeof(float32));
if (_byteswap && !_istream->fail())
{
osg::swapBytes4(buf);
memcpy(&d,buf,sizeof(float32));
}
return d;
}
float64 DataInputStream::readFloat64(float64 def) const
{
float64 d=def;
char buf[sizeof(float64)];
read(buf, sizeof(float64));
if (_byteswap && !_istream->fail())
{
osg::swapBytes8(buf);
memcpy(&d,buf,sizeof(float64));
}
return d;
}
void DataInputStream::readCharArray(char* data, int size) const
{
read(data, size);
}
std::string DataInputStream::readString(int size) const
{
char* buf = new char[size+1];
read(buf,size);
buf[size] = '\0';
std::string str = buf;
delete [] buf;
return str;
}
osg::Vec4f DataInputStream::readColor32() const
{
uint8 alpha = readUInt8();
uint8 blue = readUInt8();
uint8 green = readUInt8();
uint8 red = readUInt8();
osg::Vec4f color((float)red/255,(float)green/255,(float)blue/255,1);
return color;
}
osg::Vec2f DataInputStream::readVec2f() const
{
float32 x = readFloat32();
float32 y = readFloat32();
osg::Vec2f vec(x,y);
return vec;
}
osg::Vec3f DataInputStream::readVec3f() const
{
float32 x = readFloat32();
float32 y = readFloat32();
float32 z = readFloat32();
osg::Vec3f vec(x,y,z);
return vec;
}
osg::Vec3d DataInputStream::readVec3d() const
{
float64 x = readFloat64();
float64 y = readFloat64();
float64 z = readFloat64();
osg::Vec3d vec(x,y,z);
return vec;
}
int16 DataInputStream::peekInt16() const
{
// Get current read position in stream.
std::istream::pos_type pos = _istream->tellg();
int16 value = readInt16();
// Restore position
_istream->seekg(pos, std::ios_base::beg);
return value;
}
void DataInputStream::forward(std::istream::off_type _Off) const
{
seekg(_Off, std::ios_base::cur);
}
std::istream& DataInputStream::read(std::istream::char_type *_Str, std::streamsize _Count) const
{
return _istream->read(_Str, _Count);
}
std::istream& DataInputStream::seekg(std::istream::off_type _Off, std::ios_base::seekdir _Way) const
{
return _istream->seekg(_Off, _Way);
}

View File

@@ -0,0 +1,61 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_DATAINPUTSTREAM
#define FLT_DATAINPUTSTREAM 1
#include <iostream> // for ifstream
#include <string>
#include <osg/Vec3f>
#include <osg/Vec3d>
#include <osg/Vec4f>
#include "types.h"
namespace flt {
class Record;
class DataInputStream
{
public:
DataInputStream(std::istream* istream);
virtual ~DataInputStream();
int8 readInt8(int8 def=0) const;
uint8 readUInt8(uint8 def=0) const;
int16 readInt16(int16 def=0) const;
uint16 readUInt16(uint16 def=0) const;
int32 readInt32(int32 def=0) const;
uint32 readUInt32(uint32 def=0) const;
float32 readFloat32(float32 def=0) const;
float64 readFloat64(float64 def=0) const;
void readCharArray(char* data, int size) const;
std::string readString(int size) const;
osg::Vec4f readColor32() const;
osg::Vec2f readVec2f() const;
osg::Vec3f readVec3f() const;
osg::Vec3d readVec3d() const;
void forward(std::istream::off_type _Off) const;
int16 peekInt16() const;
inline std::istream& operator() () { return *_istream; }
protected:
virtual std::istream& read(std::istream::char_type *_Str, std::streamsize _Count) const;
virtual std::istream& seekg(std::istream::off_type _Off, std::ios_base::seekdir _Way) const;
bool _byteswap;
std::istream* _istream;
};
} // end namespace
#endif

View File

@@ -0,0 +1,114 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "Document.h"
using namespace flt;
Document::Document() :
_done(false),
_level(0),
_subfaceLevel(0),
_version(0),
_unitScale(1.0),
_defaultDOFAnimationState(false),
_useTextureAlphaForTransparancyBinning(true),
_doUnitsConversion(true),
_desiredUnits(METERS)
{
}
Document::~Document()
{
}
void Document::pushLevel()
{
_levelStack.push_back(_currentPrimaryRecord.get());
_level++;
}
void Document::popLevel()
{
_levelStack.pop_back();
if (!_levelStack.empty())
_currentPrimaryRecord = _levelStack.back().get();
if (--_level<=0)
_done = true;
}
void Document::pushSubface()
{
_subfaceLevel++;
}
void Document::popSubface()
{
_subfaceLevel--;
}
void Document::pushExtension()
{
if (!_currentPrimaryRecord.valid())
{
osg::notify(osg::WARN) << "No current primary in Document::pushExtension()." << std::endl;
return;
}
_extensionStack.push_back(_currentPrimaryRecord.get());
}
void Document::popExtension()
{
_currentPrimaryRecord=_extensionStack.back().get();
if (!_currentPrimaryRecord.valid())
{
osg::notify(osg::WARN) << "Can't descide primary in Document::popExtension()." << std::endl;
return;
}
_extensionStack.pop_back();
}
osg::Node* Document::getInstanceDefinition(int no)
{
InstanceDefinitionMap::iterator itr = _instanceDefinitionMap.find(no);
if (itr != _instanceDefinitionMap.end())
return (*itr).second.get();
return NULL;
}
double flt::unitsToMeters(CoordUnits unit)
{
switch (unit)
{
case METERS:
return 1.0;
case KILOMETERS:
return 1000.0;
case FEET:
return 0.3048;
case INCHES:
return 0.02540;
case NAUTICAL_MILES:
return 1852.0;
}
return 1.0;
}

View File

@@ -0,0 +1,221 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_FLIGHTDATA_H
#define FLT_FLIGHTDATA_H 1
#include <vector>
#include <osg/Notify>
#include <osg/Transform>
#include <osg/Geometry>
#include <osgDB/ReaderWriter>
#include "types.h"
#include "Record.h"
#include "Pools.h"
namespace flt {
class Header;
class PushLevel;
class PopLevel;
enum Version
{
VERSION_11 = 11,
VERSION_12 = 12,
VERSION_13 = 13,
VERSION_14 = 14,
VERSION_14_1 = 14,
VERSION_14_2 = 1420,
VERSION_15_1 = 1510,
VERSION_15_4 = 1540,
VERSION_15_5 = 1550,
VERSION_15_6 = 1560,
VERSION_15_7 = 1570,
VERSION_15_8 = 1580,
VERSION_16_0 = 1600
};
enum CoordUnits {
METERS = 0,
KILOMETERS = 1,
FEET = 4,
INCHES = 5,
NAUTICAL_MILES = 8
};
double unitsToMeters(CoordUnits unit);
enum Projection {
FLAT_EARTH = 0,
TRAPEZOIDAL = 1,
ROUND_EARTH = 2,
LAMBERT = 3,
UTM = 4,
GEODETIC = 5,
GEOCENTRIC = 6
};
enum Ellipsoid {
WGS_1984 = 0,
WGS_1972 = 1,
BESSEL = 2,
CLARKE_1866 = 3,
NAD_1927 = 4
};
class Document
{
public:
Document();
virtual ~Document();
void setOptions(const osgDB::ReaderWriter::Options* options) { _options = options; }
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
// Current primar record
void setCurrentPrimaryRecord(PrimaryRecord* record) {_currentPrimaryRecord=record; }
PrimaryRecord* getCurrentPrimaryRecord() { return _currentPrimaryRecord.get(); }
const PrimaryRecord* getCurrentPrimaryRecord() const { return _currentPrimaryRecord.get(); }
// Level stack
PrimaryRecord* getTopOfLevelStack();
void pushLevel();
void popLevel();
// Subface stack
void pushSubface();
void popSubface();
// Extension stack
void pushExtension();
void popExtension();
void setHeaderNode(osg::Node* node) { _osgHeader = node; }
osg::Node* getHeaderNode() { return _osgHeader.get(); }
// Instance definitions
void setInstanceDefinition(int no, osg::Node* node) { _instanceDefinitionMap[no] = node; }
osg::Node* getInstanceDefinition(int no);
uint32 version() const { return _version; }
bool done() const { return _done; }
int level() const { return _level; }
int subfaceLevel() const { return _subfaceLevel; }
double unitScale() const { return _unitScale; }
// Pools
void setVertexPool(VertexPool* vp) { _vertexPool = vp; }
VertexPool* getVertexPool() { return _vertexPool.get(); }
const VertexPool* getVertexPool() const { return _vertexPool.get(); }
void setColorPool(ColorPool* cp) { _colorPool = cp; }
ColorPool* getColorPool() { return _colorPool.get(); }
const ColorPool* getColorPool() const { return _colorPool.get(); }
TexturePool* getOrCreateTexturePool();
MaterialPool* getOrCreateMaterialPool();
LightPointAppearancePool* getOrCreateLightPointAppearancePool();
ShaderPool* getOrCreateShaderPool();
// Options
void setDefaultDOFAnimationState(bool state) { _defaultDOFAnimationState = state; }
bool getDefaultDOFAnimationState() const { return _defaultDOFAnimationState; }
void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; }
bool getUseTextureAlphaForTransparancyBinning() const { return _useTextureAlphaForTransparancyBinning; }
void setDoUnitsConversion(bool flag) { _doUnitsConversion=flag; }
bool getDoUnitsConversion() const { return _doUnitsConversion; }
void setDesiredUnits(CoordUnits units ) { _desiredUnits=units; }
CoordUnits getDesiredUnits() const { return _desiredUnits; }
protected:
// Options
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options;
bool _defaultDOFAnimationState;
bool _useTextureAlphaForTransparancyBinning;
bool _doUnitsConversion;
CoordUnits _desiredUnits;
friend class Header;
bool _done;
int _level;
int _subfaceLevel;
double _unitScale;
uint32 _version;
// Header data
osg::ref_ptr<osg::Node> _osgHeader;
osg::ref_ptr<VertexPool> _vertexPool;
osg::ref_ptr<ColorPool> _colorPool;
osg::ref_ptr<TexturePool> _texturePool;
osg::ref_ptr<MaterialPool> _materialPool;
osg::ref_ptr<LightPointAppearancePool> _lightPointAppearancePool;
osg::ref_ptr<ShaderPool> _shaderPool;
osg::ref_ptr<PrimaryRecord> _currentPrimaryRecord;
typedef std::vector<osg::ref_ptr<PrimaryRecord> > LevelStack;
LevelStack _levelStack;
LevelStack _extensionStack;
typedef std::map<int,osg::ref_ptr<osg::Node> > InstanceDefinitionMap;
InstanceDefinitionMap _instanceDefinitionMap;
};
inline TexturePool* Document::getOrCreateTexturePool()
{
if (!_texturePool.valid())
_texturePool = new TexturePool;
return _texturePool.get();
}
inline MaterialPool* Document::getOrCreateMaterialPool()
{
if (!_materialPool.valid())
_materialPool = new MaterialPool;
return _materialPool.get();
}
inline LightPointAppearancePool* Document::getOrCreateLightPointAppearancePool()
{
if (!_lightPointAppearancePool.valid())
_lightPointAppearancePool = new LightPointAppearancePool;
return _lightPointAppearancePool.get();
}
inline ShaderPool* Document::getOrCreateShaderPool()
{
if (!_shaderPool.valid())
_shaderPool = new ShaderPool;
return _shaderPool.get();
}
inline PrimaryRecord* Document::getTopOfLevelStack()
{
// Anything on the level stack?
if (_levelStack.empty())
return NULL;
return _levelStack.back().get();
}
} // end namespace
#endif

View File

@@ -0,0 +1,34 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
AncillaryRecords.cpp \
AttrData.cpp \
ControlRecords.cpp \
DataInputStream.cpp \
Document.cpp \
GeometryRecords.cpp \
LightPointRecords.cpp \
PaletteRecords.cpp \
Pools.cpp \
PrimaryRecords.cpp \
ReaderWriterATTR.cpp \
ReaderWriterFLT.cpp \
Record.cpp \
RecordInputStream.cpp \
Registry.cpp \
ReservedRecords.cpp \
RoadRecords.cpp \
Vertex.cpp \
VertexRecords.cpp \
INC += -I$(THISDIR)
LIBS += -losgSim -losgText $(OSG_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = OpenFlight
include $(TOPDIR)/Make/cygwin_plugin_def
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
include $(TOPDIR)/Make/makerules

View File

@@ -0,0 +1,625 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <cassert>
#include <osg/Geode>
#include <osg/Billboard>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osg/CullFace>
#include <osg/PolygonOffset>
#include <osg/Depth>
#include <osg/ShadeModel>
#include <osg/BlendFunc>
#include <osgUtil/Tesselator>
#include <osgUtil/SmoothingVisitor>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
class Face : public PrimaryRecord
{
// flags
static const unsigned int TERRAIN_BIT = 0x80000000u >> 0;
static const unsigned int NO_COLOR_BIT = 0x80000000u >> 1;
static const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2;
static const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3;
static const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout
static const unsigned int HIDDEN_BIT = 0x80000000u >> 5;
static const unsigned int ROOFLINE_BIT = 0x80000000u >> 6;
osg::Vec4 _primaryColor;
int32 _IRColor;
int16 _relativePriority;
uint8 _drawFlag;
uint8 _texturedWhite;
int16 _primaryNameIndex;
int16 _secondaryNameIndex;
uint8 _template;
int _detailTexture;
int _textureIndex;
int _materialIndex;
int16 _surface;
int16 _feature;
int32 _IRMaterial;
uint16 _transparency;
uint8 _influenceLOD;
uint8 _linestyle;
uint32 _flags;
uint8 _lightMode;
osg::Vec4 _primaryPackedColor;
osg::Vec4 _secondaryPackedColor;
int _textureMappingIndex;
int _primaryColorIndex;
int _alternateColorIndex;
int _shaderIndex;
osg::ref_ptr<osg::Geode> _geode;
osg::ref_ptr<osg::Geometry> _geometry;
public:
Face() :
_primaryColor(1,1,1,1)
{
}
META_Record(Face)
META_setID(_geode)
META_setComment(_geode)
META_setMatrix(_geode)
META_setMultitexture(_geode)
// draw mode
enum DrawMode
{
SOLID_BACKFACED = 0,
SOLID_NO_BACKFACE = 1,
WIREFRAME_CLOSED = 2,
WIREFRAME_NOT_CLOSED = 3,
SURROUND_ALTERNATE_COLOR = 4,
OMNIDIRECTIONAL_LIGHT = 8,
UNIDIRECTIONAL_LIGHT = 9,
BIDIRECTIONAL_LIGHT = 10
};
inline DrawMode getDrawMode() const { return (DrawMode)_drawFlag; }
// lighting
enum LightMode
{
FACE_COLOR = 0,
VERTEX_COLOR = 1,
FACE_COLOR_LIGHTING = 2,
VERTEX_COLOR_LIGHTING = 3
};
inline LightMode getLightMode() const { return (LightMode)_lightMode; }
inline bool isLit() const { return (_lightMode==FACE_COLOR_LIGHTING) || (_lightMode==VERTEX_COLOR_LIGHTING); }
inline bool isGouraud() const { return (_lightMode==VERTEX_COLOR) || (_lightMode==VERTEX_COLOR_LIGHTING); }
// flags
inline bool noColor() const { return (_flags & NO_COLOR_BIT)!=0; }
inline bool isHidden() const { return (_flags & HIDDEN_BIT)!=0; }
inline bool isTerrain() const { return (_flags & TERRAIN_BIT)!=0; }
inline bool isFootprint() const { return (_flags & FOOTPRINT_BIT)!=0; }
inline bool isRoofline() const { return (_flags & ROOFLINE_BIT)!=0; }
inline bool packedColorMode() const { return (_flags & PACKED_COLOR_BIT)!=0; }
// billboard
enum TemplateMode
{
FIXED_NO_ALPHA_BLENDING = 0,
FIXED_ALPHA_BLENDING = 1,
AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2,
POINT_ROTATE_WITH_ALPHA_BLENDING = 4
};
inline TemplateMode getTemplateMode() const { return (TemplateMode)_template; }
// transparency & alpha
inline bool isAlphaBlend() const
{
return (_template==FIXED_ALPHA_BLENDING) ||
(_template==AXIAL_ROTATE_WITH_ALPHA_BLENDING) ||
(_template==POINT_ROTATE_WITH_ALPHA_BLENDING);
}
virtual osg::Vec4 getPrimaryColor() const { return _primaryColor; }
inline int getMaterialIndex() const { return _materialIndex; }
inline int getTextureIndex() const { return _textureIndex; }
inline int getTextureMappingIndex() const { return _textureMappingIndex; }
inline float getTransparency() const { return (float)_transparency / 65535.0f; }
inline bool isTransparent() const { return _transparency > 0; }
virtual void addChild(osg::Node& child)
{
// Add subface to parent.
if (_parent.valid())
_parent->addChild(child);
}
virtual void addVertex(Vertex& vertex)
{
osg::Vec3Array* vertices = getOrCreateVertexArray(*_geometry);
vertices->push_back(vertex._coord);
if (isGouraud())
{
osg::Vec4Array* colors = getOrCreateColorArray(*_geometry);
if (vertex.validColor())
{
colors->push_back(vertex._color);
}
else
{
// Use face color if vertex color is -1 in a gouraud polygon.
// http://www.multigen-paradigm.com/ubb/Forum1/HTML/000967.html
colors->push_back(_primaryColor);
}
}
if (vertex.validNormal())
{
osg::Vec3Array* normals = getOrCreateNormalArray(*_geometry);
normals->push_back(vertex._normal);
}
if (vertex.validUV())
{
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,0);
UVs->push_back(vertex._uv);
}
}
virtual void addVertexUV(int unit, const osg::Vec2& uv)
{
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,unit);
UVs->push_back(uv);
}
virtual void addMorphVertex(Vertex& vertex0, Vertex& vertex100)
{
osg::Vec3Array* vertices = getOrCreateVertexArray(*_geometry);
vertices->push_back(vertex0._coord);
if (isGouraud())
{
osg::Vec4Array* colors = getOrCreateColorArray(*_geometry);
if (vertex0.validColor())
{
colors->push_back(vertex0._color);
}
else
{
// Use face color if vertex color is -1 in a gouraud polygon.
// http://www.multigen-paradigm.com/ubb/Forum1/HTML/000967.html
colors->push_back(_primaryColor);
}
}
if (vertex0.validNormal())
{
osg::Vec3Array* normals = getOrCreateNormalArray(*_geometry);
normals->push_back(vertex0._normal);
}
if (vertex0.validUV())
{
osg::Vec2Array* UVs = getOrCreateTextureArray(*_geometry,0);
UVs->push_back(vertex0._uv);
}
}
protected:
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
_IRColor = in.readInt32();
_relativePriority = in.readInt16();
_drawFlag = in.readUInt8();
_texturedWhite = in.readUInt8();
_primaryNameIndex = in.readInt16(-1);
_secondaryNameIndex = in.readInt16(-1);
in.forward(1);
_template = in.readUInt8(FIXED_NO_ALPHA_BLENDING);
_detailTexture = in.readInt16(-1);
_textureIndex = in.readInt16(-1);
_materialIndex = in.readInt16(-1);
_surface = in.readInt16();
_feature = in.readInt16();
_IRMaterial = in.readInt32(-1);
_transparency = in.readUInt16(0);
// version > 13
_influenceLOD = in.readUInt8();
_linestyle = in.readUInt8();
_flags = in.readUInt32(0);
_lightMode = in.readUInt8(FACE_COLOR);
in.forward(7);
_primaryPackedColor = in.readColor32();
_secondaryPackedColor = in.readColor32();
// version >= VERSION_15_1
_textureMappingIndex = in.readInt16(-1);
in.forward(2);
_primaryColorIndex = in.readInt32(-1);
_alternateColorIndex = in.readInt32(-1);
// version >= 16
in.forward(2);
_shaderIndex = in.readInt16(-1);
// Create Geode or Billboard.
switch (_template)
{
case AXIAL_ROTATE_WITH_ALPHA_BLENDING:
{
osg::Billboard* billboard = new osg::Billboard;
billboard->setMode(osg::Billboard::AXIAL_ROT);
_geode = billboard;
}
break;
case POINT_ROTATE_WITH_ALPHA_BLENDING:
{
osg::Billboard* billboard = new osg::Billboard;
billboard->setMode(osg::Billboard::POINT_ROT_WORLD);
_geode = billboard;
}
break;
default:
_geode = new osg::Geode;
}
_geode->setDataVariance(osg::Object::STATIC);
_geode->setName(id);
_geometry = new osg::Geometry;
_geometry->setDataVariance(osg::Object::STATIC);
_geode->addDrawable(_geometry.get());
// StateSet
osg::StateSet* stateset = _geode->getOrCreateStateSet();
// Hidden
if (isHidden())
_geode->setNodeMask(0);
// Face color
if (_texturedWhite!=0 && _textureIndex>=0)
{
_primaryColor = osg::Vec4(1,1,1,1);
}
else
{
if (packedColorMode())
{
_primaryColor = _primaryPackedColor;
}
else
{
if (document.version() < VERSION_15_1)
_primaryColor = document.getColorPool()->getColor(_primaryNameIndex);
else // >= VERSION_15_1
_primaryColor = document.getColorPool()->getColor(_primaryColorIndex);
}
}
// Lighting
stateset->setMode(GL_LIGHTING, isLit() ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
// Material
bool isTransparentMaterial = false;
if (isLit())
{
osg::Vec4 col = _primaryColor;
col.a() = 1.0f - getTransparency();
osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(_materialIndex,col);
stateset->setAttribute(material);
isTransparentMaterial = material->getDiffuse(osg::Material::FRONT).a() < 0.99f;
}
// Shaders
if (_shaderIndex >= 0)
{
ShaderPool* sp = document.getOrCreateShaderPool();
osg::Program* program = sp->get(_shaderIndex);
if (program)
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
}
// Texture
TexturePool* tp = document.getOrCreateTexturePool();
osg::StateSet* textureStateSet = tp->get(_textureIndex);
if (textureStateSet)
{
// Merge face stateset with texture stateset
stateset->merge(*textureStateSet);
}
// Translucent image?
bool isImageTranslucent = false;
if (textureStateSet)
{
if (document.getUseTextureAlphaForTransparancyBinning())
{
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>(textureStateSet->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
if (texture)
{
osg::Image* image = texture->getImage();
if (image && image->isImageTranslucent())
isImageTranslucent = true;
}
}
}
// Enable alpha blend?
if (isAlphaBlend() || isTransparent() || isTransparentMaterial || isImageTranslucent)
{
stateset->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA), osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
// Cull face
switch(_drawFlag)
{
case SOLID_BACKFACED: // Enable backface culling
stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON);
break;
case SOLID_NO_BACKFACE: // Disable backface culling
stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
break;
}
// Subface
if (document.subfaceLevel() > 0)
{
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
polyoffset->setFactor(-10.0f);
polyoffset->setUnits(-40.0f);
stateset->setAttributeAndModes(polyoffset, osg::StateAttribute::ON);
osg::Depth* depth = new osg::Depth;
depth->setWriteMask(false);
stateset->setAttribute(depth);
stateset->setRenderBinDetails(document.subfaceLevel(),"RenderBin");
}
// Add to parent.
if (_parent.valid())
_parent->addChild(*_geode);
}
osg::PrimitiveSet::Mode getPrimitiveSetMode(int numVertices)
{
switch(getDrawMode())
{
case WIREFRAME_NOT_CLOSED:
return osg::PrimitiveSet::LINE_STRIP;
case WIREFRAME_CLOSED:
return osg::PrimitiveSet::LINE_LOOP;
case OMNIDIRECTIONAL_LIGHT:
case UNIDIRECTIONAL_LIGHT:
case BIDIRECTIONAL_LIGHT:
return osg::PrimitiveSet::POINTS;
default: break;
}
switch (numVertices)
{
case 1: return osg::PrimitiveSet::POINTS;
case 2: return osg::PrimitiveSet::LINES;
case 3: return osg::PrimitiveSet::TRIANGLES;
case 4: return osg::PrimitiveSet::QUADS;
default: break;
}
return osg::PrimitiveSet::POLYGON;
}
virtual ~Face()
{
if (_geode.valid())
{
for (unsigned int i=0; i<_geode->getNumDrawables(); ++i)
{
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(_geode->getDrawable(i));
if (geometry)
{
osg::Array* vertices = geometry->getVertexArray();
if (vertices)
{
GLint first = 0;
GLsizei count = vertices->getNumElements();
osg::PrimitiveSet::Mode mode = getPrimitiveSetMode(count);
geometry->addPrimitiveSet(new osg::DrawArrays(mode,first,count));
}
// Color binding
if (isGouraud())
{
// Color per vertex
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
}
else
{
// Color per face
osg::Vec4 col = getPrimaryColor();
col[3] = 1.0f - getTransparency();
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0] = col;
geometry->setColorArray(colors);
}
// Normal binding
if (isLit())
{
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX );
}
else
{
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->setNormalArray(NULL);
}
}
}
}
}
};
RegisterRecordProxy<Face> g_Face(FACE_OP);
RegisterRecordProxy<Face> g_Mesh(MESH_OP);
/** VertexList -
* The VertexList is a leaf record.
* Possible parents: Face, Mesh & LightPoint
*/
class VertexList : public PrimaryRecord
{
public:
VertexList() {}
META_Record(VertexList)
virtual void addVertex(Vertex& vertex)
{
// forward vertex to parent.
if (_parent.valid())
_parent->addVertex(vertex);
}
virtual void addVertexUV(int layer,const osg::Vec2& uv)
{
// forward uv to parent.
if (_parent.valid())
_parent->addVertexUV(layer,uv);
}
protected:
virtual ~VertexList() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
VertexPool* vp = document.getVertexPool();
if (vp)
{
int vertices = (in.getRecordSize()-4) / 4;
// Use the Vertex pool as a record stream.
RecordInputStream inVP(vp);
for (int n=0; n<vertices; n++)
{
// Get position of vertex.
uint32 pos = in.readUInt32();
// Get vertex from vertex pool.
inVP().seekg((std::istream::pos_type)pos);
inVP.readRecord(document);
}
}
}
};
RegisterRecordProxy<VertexList> g_VertexList(VERTEX_LIST_OP);
/** MorphVertexList -
* The MorphVertexList is a leaf record.
*/
class MorphVertexList : public PrimaryRecord
{
enum Mode
{
UNDEFINED,
MORPH_0,
MORPH_100
};
Mode _mode;
Vertex _vertex0;
Vertex _vertex100;
public:
MorphVertexList():
_mode(UNDEFINED)
{
}
META_Record(MorphVertexList)
virtual void addVertex(Vertex& vertex)
{
switch (_mode)
{
case MORPH_0:
_vertex0 = vertex;
break;
case MORPH_100:
_vertex100 = vertex;
// forward vertex to parent.
if (_parent.valid())
_parent->addMorphVertex(_vertex0, _vertex100);
break;
}
}
//virtual void addVertexUV(int layer,const osg::Vec2& uv)
//{
// // forward uv to parent.
// if (_parent.valid())
// _parent->addVertexUV(layer,uv);
//}
protected:
virtual ~MorphVertexList() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
VertexPool* vp = document.getVertexPool();
if (vp)
{
int vertices = (in.getRecordSize()-4) / 8;
// Use the Vertex pool as a record stream.
RecordInputStream inVP(vp);
for (int n=0; n<vertices; n++)
{
// Get position of vertex.
uint32 offset0 = in.readUInt32();
uint32 offset100 = in.readUInt32();
// Get vertex from vertex pool.
// 0%
_mode = MORPH_0;
inVP().seekg((std::istream::pos_type)offset0);
inVP.readRecord(document);
// 100%
_mode = MORPH_100;
inVP().seekg((std::istream::pos_type)offset100);
inVP.readRecord(document);
}
}
}
};
RegisterRecordProxy<MorphVertexList> g_MorphVertexList(MORPH_VERTEX_LIST_OP);
} // end namespace

View File

@@ -0,0 +1,314 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osgSim/LightPointNode>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
using namespace flt;
/** LightPoint
*/
class LightPoint : public PrimaryRecord
{
enum Directionality
{
OMNIDIRECTIONAL = 0,
UNIDIRECTIONAL = 1,
BIDIRECTIONAL = 2
};
// flags
static const unsigned int NO_BACK_COLOR_BIT = 0x80000000u >> 1;
int16 _material;
int16 _feature;
osg::Vec4f _backColor;
int32 _displayMode;
float32 _intensityFront;
float32 _intensityBack;
float32 _minDefocus;
float32 _maxDefocus;
int32 _fadeMode;
int32 _fogPunchMode;
int32 _directionalMode;
int32 _rangeMode;
float32 _minPixelSize;
float32 _maxPixelSize;
float32 _actualPixelSize;
float32 _transparentFalloff;
float32 _transparentFalloffExponent;
float32 _transparentFalloffScalar;
float32 _transparentFalloffClamp;
float32 _fog;
float32 _sizeDifferenceThreshold;
int32 _directionality;
float32 _lobeHorizontal;
float32 _lobeVertical;
float32 _lobeRoll;
float32 _falloff;
float32 _ambientIntensity;
float32 _animationPeriod;
float32 _animationPhaseDelay;
float32 _animationPeriodEnable;
float32 _significance;
int32 _drawOrder;
uint32 _flags;
osg::Vec3f _animationAxis;
osg::ref_ptr<osgSim::LightPointNode> _lpn;
public:
LightPoint() {}
META_Record(LightPoint)
META_setID(_lpn)
META_setComment(_lpn)
META_setMatrix(_lpn)
// Add lightpoint, add two if bidirectional.
virtual void addVertex(Vertex& vertex)
{
osgSim::LightPoint lp;
lp._position = vertex._coord;
lp._radius = 0.5f * _actualPixelSize;
lp._intensity = _intensityFront;
// color
lp._color = (vertex.validColor()) ? vertex._color : osg::Vec4(1,1,1,1);
// sector
bool directional = (_directionality==UNIDIRECTIONAL) || (_directionality==BIDIRECTIONAL);
if (directional && vertex.validNormal())
{
lp._sector = new osgSim::DirectionalSector(
vertex._normal,
osg::DegreesToRadians(_lobeHorizontal),
osg::DegreesToRadians(_lobeVertical),
osg::DegreesToRadians(_lobeRoll));
}
_lpn->addLightPoint(lp);
// Create a new lightpoint if bi-directional.
if ((_directionality==BIDIRECTIONAL) && vertex.validNormal())
{
// back intensity
lp._intensity = _intensityBack;
// back color
if (!(_flags & NO_BACK_COLOR_BIT))
lp._color = _backColor;
// back sector
lp._sector = new osgSim::DirectionalSector(
-vertex._normal,
osg::DegreesToRadians(_lobeHorizontal),
osg::DegreesToRadians(_lobeVertical),
osg::DegreesToRadians(_lobeRoll));
_lpn->addLightPoint(lp);
}
}
protected:
virtual ~LightPoint() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
_material = in.readInt16();
_feature = in.readInt16();
_backColor = in.readColor32();
_displayMode = in.readInt32();
_intensityFront = in.readFloat32();
_intensityBack = in.readFloat32();
_minDefocus = in.readFloat32();
_maxDefocus = in.readFloat32();
_fadeMode = in.readInt32();
_fogPunchMode = in.readInt32();
_directionalMode = in.readInt32();
_rangeMode = in.readInt32();
_minPixelSize = in.readFloat32(); // * document.unitScale();
_maxPixelSize = in.readFloat32(); // * document.unitScale();
_actualPixelSize = in.readFloat32(); // * document.unitScale();
_transparentFalloff = in.readFloat32();
_transparentFalloffExponent = in.readFloat32();
_transparentFalloffScalar = in.readFloat32();
_transparentFalloffClamp = in.readFloat32();
_fog = in.readFloat32();
in.forward(4);
_sizeDifferenceThreshold = in.readFloat32();
_directionality = in.readInt32();
_lobeHorizontal = in.readFloat32();
_lobeVertical = in.readFloat32();
_lobeRoll = in.readFloat32();
_falloff = in.readFloat32();
_ambientIntensity = in.readFloat32();
_animationPeriod = in.readFloat32();
_animationPhaseDelay = in.readFloat32();
_animationPeriodEnable = in.readFloat32();
_significance = in.readFloat32();
_drawOrder = in.readInt32();
_flags = in.readUInt32(0);
_animationAxis = in.readVec3f();
_lpn = new osgSim::LightPointNode;
_lpn->setName(id);
_lpn->setMinPixelSize(_minPixelSize);
_lpn->setMaxPixelSize(_maxPixelSize);
// Add to parent
if (_parent.valid())
_parent->addChild(*_lpn);
}
};
RegisterRecordProxy<LightPoint> g_LightPoint(LIGHT_POINT_OP);
/** IndexedLightPoint
*/
class IndexedLightPoint : public PrimaryRecord
{
enum Directionality
{
OMNIDIRECTIONAL = 0,
UNIDIRECTIONAL = 1,
BIDIRECTIONAL = 2
};
// flags
static const unsigned int NO_BACK_COLOR_BIT = 0x80000000u >> 1;
osg::ref_ptr<osgSim::LightPointNode> _lpn;
osg::ref_ptr<LPAppearance> _appearance;
public:
IndexedLightPoint() {}
META_Record(IndexedLightPoint)
META_setID(_lpn)
META_setComment(_lpn)
META_setMatrix(_lpn)
// Add lightpoint, add two if bidirectional.
virtual void addVertex(Vertex& vertex)
{
if (_appearance.valid())
{
osgSim::LightPoint lp;
lp._position = vertex._coord;
lp._radius = 0.5f * _appearance->actualPixelSize;
lp._intensity = _appearance->intensityFront;
// color
lp._color = (vertex.validColor()) ? vertex._color : osg::Vec4(1,1,1,1);
// sector
bool directional = (_appearance->directionality==UNIDIRECTIONAL) || (_appearance->directionality==BIDIRECTIONAL);
if (directional && vertex.validNormal())
{
lp._sector = new osgSim::DirectionalSector(
vertex._normal,
osg::DegreesToRadians(_appearance->horizontalLobeAngle),
osg::DegreesToRadians(_appearance->verticalLobeAngle),
osg::DegreesToRadians(_appearance->lobeRollAngle));
}
_lpn->addLightPoint(lp);
// Create a new lightpoint if bi-directional.
if ((_appearance->directionality==BIDIRECTIONAL) && vertex.validNormal())
{
// back intensity
lp._intensity = _appearance->intensityBack;
// back color
if (!(_appearance->flags & NO_BACK_COLOR_BIT))
lp._color = _appearance->backColor;
// back sector
lp._sector = new osgSim::DirectionalSector(
-vertex._normal,
osg::DegreesToRadians(_appearance->horizontalLobeAngle),
osg::DegreesToRadians(_appearance->verticalLobeAngle),
osg::DegreesToRadians(_appearance->lobeRollAngle));
_lpn->addLightPoint(lp);
}
}
}
protected:
virtual ~IndexedLightPoint() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
int32 appearanceIndex = in.readInt32();
int32 animationIndex = in.readInt32();
int32 drawOrder = in.readInt32(); // for calligraphic lights
LightPointAppearancePool* lpaPool = document.getOrCreateLightPointAppearancePool();
_appearance = lpaPool->get(appearanceIndex);
_lpn = new osgSim::LightPointNode;
_lpn->setName(id);
if (_appearance.valid())
{
_lpn->setMinPixelSize(_appearance->minPixelSize);
_lpn->setMaxPixelSize(_appearance->maxPixelSize);
}
// Add to parent
if (_parent.valid())
_parent->addChild(*_lpn);
}
};
RegisterRecordProxy<IndexedLightPoint> g_IndexedLightPoint(INDEXED_LIGHT_POINT_OP);
/** LightPointSystem
*/
class LightPointSystem : public PrimaryRecord
{
public:
LightPointSystem() {}
META_Record(LightPointSystem)
protected:
virtual ~LightPointSystem() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
osg::notify(osg::INFO) << "ID: " << id << std::endl;
osg::Group* group = new osg::Group;
group->setName(id);
if (_parent.valid())
_parent->addChild(*group);
}
};
RegisterRecordProxy<LightPointSystem> g_LightPointSystem(LIGHT_POINT_SYSTEM_OP);

View File

@@ -0,0 +1,635 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <cassert>
#include <osg/Texture2D>
#include <osg/TexEnv>
#include <osg/BlendFunc>
#include <osgSim/LightPointNode>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include "Registry.h"
#include "Document.h"
#include "AttrData.h"
#include "RecordInputStream.h"
namespace flt {
class VertexPalette : public Record
{
public:
VertexPalette() {}
META_Record(VertexPalette)
protected:
virtual ~VertexPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
uint32 paletteSize = in.readUInt32();
VertexPool* vp = new VertexPool(paletteSize);
in.moveToStartOfRecord();
in().read(vp->str(),paletteSize); // read beyond record end so use isream::read().
document.setVertexPool(vp);
in.setEndOfRecord(in.getStartOfRecord()+(std::istream::pos_type)paletteSize);
}
};
RegisterRecordProxy<VertexPalette> g_VertexPalette(VERTEX_PALETTE_OP);
class ColorPalette : public Record
{
public:
ColorPalette() {}
META_Record(ColorPalette)
protected:
virtual ~ColorPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
if (document.version() > VERSION_13)
{
bool oldVersion = false;
bool colorNameSection = in.getRecordSize() > 4228;
int maxColors = (document.version()>=VERSION_15_1) ? 1024 : 512;
// It might be less.
if (!colorNameSection)
{
// Max colors calculated by record size.
int maxColorsByRecordSize = (in.getRecordBodySize()-128) / 4;
if (maxColorsByRecordSize < maxColors)
maxColors = maxColorsByRecordSize;
}
ColorPool* cp = new ColorPool(oldVersion,maxColors);
document.setColorPool(cp);
in.forward(128);
for (int i=0; i<maxColors; i++)
{
uint8 alpha = in.readUInt8(1);
uint8 blue = in.readUInt8(1);
uint8 green = in.readUInt8(1);
uint8 red = in.readUInt8(1);
(*cp)[i] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,1);
}
}
else // version <= 13
{
bool oldVersion = true;
int maxColors = 32+56;
ColorPool* cp = new ColorPool(oldVersion,maxColors);
document.setColorPool(cp);
// variable intensity
for (int i=0; i < 32; i++)
{
uint16 red = in.readUInt16(1);
uint16 green = in.readUInt16(1);
uint16 blue = in.readUInt16(1);
(*cp)[i] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,1);
}
// fixed intensity
for (int i=0; i < 56; i++)
{
uint16 red = in.readUInt16(1);
uint16 green = in.readUInt16(1);
uint16 blue = in.readUInt16(1);
(*cp)[i+32] = osg::Vec4((float)red/255,(float)green/255,(float)blue/255,1);
}
}
}
};
RegisterRecordProxy<ColorPalette> g_ColorPalette(COLOR_PALETTE_OP);
class NameTable : public Record
{
public:
NameTable() {}
META_Record(NameTable)
protected:
virtual ~NameTable() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
}
};
RegisterRecordProxy<NameTable> g_NameTable(NAME_TABLE_OP);
class MaterialPalette : public Record
{
public:
MaterialPalette() {}
META_Record(MaterialPalette)
protected:
virtual ~MaterialPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int32 index = in.readInt32();
std::string name = in.readString(12);
uint32 flags = in.readUInt32();
osg::Vec3f ambient = in.readVec3f();
osg::Vec3f diffuse = in.readVec3f();
osg::Vec3f specular = in.readVec3f();
osg::Vec3f emissive = in.readVec3f();
float32 shininess = in.readFloat32();
float32 alpha = in.readFloat32();
osg::Material* material = new osg::Material;
material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(ambient,alpha));
material->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(diffuse,alpha));
material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(specular,alpha));
material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(emissive,alpha));
material->setShininess(osg::Material::FRONT_AND_BACK,shininess);
MaterialPool* mp = document.getOrCreateMaterialPool();
(*mp)[index] = material;
}
};
RegisterRecordProxy<MaterialPalette> g_MaterialPalette(MATERIAL_PALETTE_OP);
class OldMaterialPalette : public Record
{
public:
OldMaterialPalette() {}
META_Record(OldMaterialPalette)
protected:
virtual ~OldMaterialPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
for (int i=0; i < 64; i++)
{
osg::Vec3f ambient = in.readVec3f();
osg::Vec3f diffuse = in.readVec3f();
osg::Vec3f specular = in.readVec3f();
osg::Vec3f emissive = in.readVec3f();
float32 shininess = in.readFloat32();
float32 alpha = in.readFloat32();
uint32 flags = in.readUInt32();
std::string name = in.readString(12);
in.forward(4*28);
osg::Material* material = new osg::Material;
material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(ambient,alpha));
material->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(diffuse,alpha));
material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(specular,alpha));
material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(emissive,alpha));
material->setShininess(osg::Material::FRONT_AND_BACK,shininess);
MaterialPool* mp = document.getOrCreateMaterialPool();
(*mp)[i] = material;
}
}
};
RegisterRecordProxy<OldMaterialPalette> g_OldMaterialPalette(OLD_MATERIAL_PALETTE_OP);
class TexturePalette : public Record
{
public:
TexturePalette() {}
META_Record(TexturePalette)
protected:
virtual ~TexturePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int maxLength = (document.version() < VERSION_14) ? 80 : 200;
std::string filename = in.readString(maxLength);
int32 index = in.readInt32(-1);
int32 x = in.readInt32();
int32 y = in.readInt32();
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(filename,document.getOptions());
if (!image.valid())
{
osg::notify(osg::WARN) << "Can't find texture (" << index << ") " << filename << std::endl;
return;
}
// Create stateset
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
osg::Texture2D* texture = new osg::Texture2D;
texture->setResizeNonPowerOfTwoHint(true);
texture->setImage(image.get());
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
// Blend mode moved to Face.
//if (image->isImageTranslucent())
//{
// stateset->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA),osg::StateAttribute::ON);
// stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
//}
// Read attribute file
std::string attrname = filename + ".attr";
osg::ref_ptr<AttrData> attr = dynamic_cast<AttrData*>(osgDB::readObjectFile(attrname,document.getOptions()));
if (attr.valid())
{
// Wrap mode
osg::Texture2D::WrapMode wrap_s = (attr->wrapMode_u==AttrData::WRAP_CLAMP) ? osg::Texture2D::CLAMP : osg::Texture2D::REPEAT;
texture->setWrap(osg::Texture2D::WRAP_S,wrap_s);
osg::Texture2D::WrapMode wrap_t = (attr->wrapMode_v==AttrData::WRAP_CLAMP) ? osg::Texture2D::CLAMP : osg::Texture2D::REPEAT;
texture->setWrap(osg::Texture2D::WRAP_T,wrap_t);
// Min filter
switch (attr->minFilterMode)
{
case AttrData::MIN_FILTER_POINT:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
break;
case AttrData::MIN_FILTER_BILINEAR:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
break;
case AttrData::MIN_FILTER_MIPMAP_POINT:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_NEAREST);
break;
case AttrData::MIN_FILTER_MIPMAP_LINEAR:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_LINEAR);
break;
case AttrData::MIN_FILTER_MIPMAP_BILINEAR:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
break;
case AttrData::MIN_FILTER_MIPMAP_TRILINEAR:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
break;
case AttrData::MIN_FILTER_BICUBIC:
case AttrData::MIN_FILTER_BILINEAR_GEQUAL:
case AttrData::MIN_FILTER_BILINEAR_LEQUAL:
case AttrData::MIN_FILTER_BICUBIC_GEQUAL:
case AttrData::MIN_FILTER_BICUBIC_LEQUAL:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
break;
default:
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
break;
}
// Mag filter
switch (attr->magFilterMode)
{
case AttrData::MAG_FILTER_POINT:
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
break;
case AttrData::MAG_FILTER_BILINEAR:
case AttrData::MAG_FILTER_BILINEAR_GEQUAL:
case AttrData::MAG_FILTER_BILINEAR_LEQUAL:
case AttrData::MAG_FILTER_SHARPEN:
case AttrData::MAG_FILTER_BICUBIC:
case AttrData::MAG_FILTER_BICUBIC_GEQUAL:
case AttrData::MAG_FILTER_BICUBIC_LEQUAL:
case AttrData::MAG_FILTER_ADD_DETAIL:
case AttrData::MAG_FILTER_MODULATE_DETAIL:
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
break;
}
osg::TexEnv* texenv = new osg::TexEnv;
switch (attr->texEnvMode)
{
case AttrData::TEXENV_MODULATE:
texenv->setMode(osg::TexEnv::MODULATE);
break;
case AttrData::TEXENV_BLEND:
texenv->setMode(osg::TexEnv::BLEND);
break;
case AttrData::TEXENV_DECAL:
texenv->setMode(osg::TexEnv::DECAL);
break;
case AttrData::TEXENV_COLOR:
texenv->setMode(osg::TexEnv::REPLACE);
break;
}
stateset->setTextureAttribute(0, texenv);
}
TexturePool* tp = document.getOrCreateTexturePool();
(*tp)[index] = stateset.get();
}
};
RegisterRecordProxy<TexturePalette> g_TexturePalette(TEXTURE_PALETTE_OP);
class EyepointAndTrackplanePalette : public Record
{
public:
EyepointAndTrackplanePalette() {}
META_Record(EyepointAndTrackplanePalette)
protected:
virtual ~EyepointAndTrackplanePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document) {}
};
RegisterRecordProxy<EyepointAndTrackplanePalette> g_EyepointAndTrackplanePalette(EYEPOINT_AND_TRACKPLANE_PALETTE_OP);
class LinkagePalette : public Record
{
public:
LinkagePalette() {}
META_Record(LinkagePalette)
protected:
virtual ~LinkagePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document) {}
};
RegisterRecordProxy<LinkagePalette> g_LinkagePalette(LINKAGE_PALETTE_OP);
class SoundPalette : public Record
{
public:
SoundPalette() {}
META_Record(SoundPalette)
protected:
virtual ~SoundPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document) {}
};
RegisterRecordProxy<SoundPalette> g_SoundPalette(SOUND_PALETTE_OP);
class LightSourcePalette : public Record
{
public:
LightSourcePalette() {}
META_Record(LightSourcePalette)
protected:
virtual ~LightSourcePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document) {}
};
RegisterRecordProxy<LightSourcePalette> g_LightSourcePalette(LIGHT_SOURCE_PALETTE_OP);
class LightPointAppearancePalette : public Record
{
public:
LightPointAppearancePalette() {}
META_Record(LightPointAppearancePalette)
protected:
virtual ~LightPointAppearancePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
osg::ref_ptr<LPAppearance> appearance = new LPAppearance;
in.forward(4);
appearance->name = in.readString(256);
appearance->index = in.readInt32(-1);
appearance->materialCode = in.readInt16();
appearance->featureID = in.readInt16();
appearance->backColor = in.readColor32();
appearance->displayMode = in.readInt32();
appearance->intensityFront = in.readFloat32();
appearance->intensityBack = in.readFloat32();
appearance->minDefocus = in.readFloat32();
appearance->maxDefocus = in.readFloat32();
appearance->fadingMode = in.readInt32();
appearance->fogPunchMode = in.readInt32();
appearance->directionalMode = in.readInt32();
appearance->rangeMode = in.readInt32();
appearance->minPixelSize = in.readFloat32();
appearance->maxPixelSize = in.readFloat32();
appearance->actualPixelSize = in.readFloat32();
appearance->transparentFalloffPixelSize = in.readFloat32();
appearance->transparentFalloffExponent = in.readFloat32();
appearance->transparentFalloffScalar = in.readFloat32();
appearance->transparentFalloffClamp = in.readFloat32();
appearance->fogScalar = in.readFloat32();
appearance->fogIntensity = in.readFloat32();
appearance->sizeDifferenceThreshold = in.readFloat32();
appearance->directionality = in.readInt32();
appearance->horizontalLobeAngle = in.readFloat32();
appearance->verticalLobeAngle = in.readFloat32();
appearance->lobeRollAngle = in.readFloat32();
appearance->directionalFalloffExponent = in.readFloat32();
appearance->directionalAmbientIntensity = in.readFloat32();
appearance->significance = in.readFloat32();
appearance->flags = in.readUInt32();
appearance->visibilityRange = in.readFloat32();
appearance->fadeRangeRatio = in.readFloat32();
appearance->fadeInDuration = in.readFloat32();
appearance->fadeOutDuration = in.readFloat32();
appearance->LODRangeRatio = in.readFloat32();
appearance->LODScale = in.readFloat32();
appearance->texturePatternIndex = in.readInt32(-1);
// Add to pool
LightPointAppearancePool* lpaPool = document.getOrCreateLightPointAppearancePool();
(*lpaPool)[appearance->index] = appearance.get();
}
};
RegisterRecordProxy<LightPointAppearancePalette> g_LightPointAppearancePalette(LIGHT_POINT_APPEARANCE_PALETTE_OP);
class LightPointAnimationPalette : public Record
{
public:
LightPointAnimationPalette() {}
META_Record(LightPointAnimationPalette)
protected:
virtual ~LightPointAnimationPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
in.forward(4);
std::string name = in.readString(256);
int32 index = in.readInt32(-1);
float32 animationPeriod = in.readFloat32();
float32 animationPhaseDelay = in.readFloat32();
float32 animationEnabledPeriod = in.readFloat32();
osg::Vec3f axisOfRotation = in.readVec3f();
uint32 flags = in.readUInt32();
int32 animationType = in.readInt32();
int32 morseCodeTiming = in.readInt32();
int32 wordRate = in.readInt32();
int32 characterRate = in.readInt32();
std::string morseCodeString = in.readString(1024);
int32 numberOfSequences = in.readInt32();
for (int n=0; n<numberOfSequences; ++n)
{
uint32 sequenceState = in.readUInt32();
float32 sequenceDuration = in.readFloat32();
osg::Vec4f sequenceColor = in.readColor32();
}
}
};
RegisterRecordProxy<LightPointAnimationPalette> g_LightPointAnimationPalette(LIGHT_POINT_ANIMATION_PALETTE_OP);
class LineStylePalette : public Record
{
public:
LineStylePalette() {}
META_Record(LineStylePalette)
protected:
virtual ~LineStylePalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
}
};
RegisterRecordProxy<LineStylePalette> g_LineStylePalette(LINE_STYLE_PALETTE_OP);
class TextureMappingPalette : public Record
{
public:
TextureMappingPalette() {}
META_Record(TextureMappingPalette)
protected:
virtual ~TextureMappingPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
}
};
RegisterRecordProxy<TextureMappingPalette> g_TextureMappingPalette(TEXTURE_MAPPING_PALETTE_OP);
class ShaderPalette : public Record
{
public:
ShaderPalette() {}
META_Record(ShaderPalette)
enum ShaderType
{
CG=0,
CGFX=1,
GLSL=2
};
protected:
virtual ~ShaderPalette() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int32 index = in.readInt32();
int32 type = in.readInt32();
std::string name = in.readString(1024);
std::string vertexProgramFilename = in.readString(1024);
std::string fragmentProgramFilename = in.readString(1024);
if (type == GLSL)
{
osg::Program* program = new osg::Program;
program->setName(name);
std::string vertexProgramFilePath = osgDB::findDataFile(vertexProgramFilename);
if (!vertexProgramFilePath.empty())
{
osg::Shader* vertexShader = osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexProgramFilePath);
if (vertexShader)
program->addShader( vertexShader );
}
std::string fragmentProgramFilePath = osgDB::findDataFile(fragmentProgramFilename);
if (!fragmentProgramFilePath.empty())
{
osg::Shader* fragmentShader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentProgramFilePath);
if (fragmentShader)
program->addShader( fragmentShader );
}
ShaderPool* shaderPool = document.getOrCreateShaderPool();
(*shaderPool)[index] = program;
}
}
};
RegisterRecordProxy<ShaderPalette> g_ShaderPalette(SHADER_PALETTE_OP);
} // end namespace

View File

@@ -0,0 +1,121 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <cassert>
#include "Pools.h"
#include "Document.h"
using namespace flt;
osg::Vec4 ColorPool::getColor(int indexIntensity) const
{
if (_old) // version <= 13
{
// bit 0-6: intensity
// bit 7-11 color index
// bit 12 fixed intensity bit
bool fixedIntensity = (indexIntensity & 0x1000) ? true : false;
unsigned int index = (fixedIntensity) ? (indexIntensity & 0x0fff)+(4096>>7) : indexIntensity >> 7;
assert(index>=0 && index<size());
osg::Vec4 col = at(index);
if (!fixedIntensity)
{
float intensity = (float)(indexIntensity & 0x7f)/127.f;
col[0] *= intensity;
col[1] *= intensity;
col[2] *= intensity;
}
return col;
}
else // version > 13
{
// bit 0-6: intensity
// bit 7-15 color index
int index = indexIntensity >> 7;
if (index<0 || index>=(int)size())
{
// color index not available.
return osg::Vec4(1,1,1,1);
}
osg::Vec4 col = at(index);
float intensity = (float)(indexIntensity & 0x7f)/127.f;
col[0] *= intensity;
col[1] *= intensity;
col[2] *= intensity;
return col;
}
}
MaterialPool::MaterialPool()
{
// Default material.
// http://www.multigen-paradigm.com/ubb/Forum1/HTML/000228.html
_defaultMaterial = new osg::Material;
_defaultMaterial->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(1,1,1,1));
_defaultMaterial->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(1,1,1,1));
_defaultMaterial->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0,0,0,1));
_defaultMaterial->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0,0,0,1));
_defaultMaterial->setShininess(osg::Material::FRONT_AND_BACK,0);
}
osg::Material* MaterialPool::get(int index)
{
iterator itr = find(index);
if (itr != end())
return (*itr).second.get();
// Use default material if not found in material palette.
return _defaultMaterial.get();
}
namespace {
osg::Vec4 finalColor(const osg::Vec4& materialColor, const osg::Vec4& faceColor)
{
return osg::Vec4(
materialColor.r() * faceColor.r(),
materialColor.g() * faceColor.g(),
materialColor.b() * faceColor.b(),
materialColor.a() * faceColor.a());
}
} // end namespace
osg::Material* MaterialPool::getOrCreateMaterial(int index, const osg::Vec4& faceColor)
{
MaterialParameters materialParam(index,faceColor);
// Look for final material.
FinalMaterialMap::iterator itr = _finalMaterialMap.find(materialParam);
if (itr != _finalMaterialMap.end())
{
// Final material found.
return (*itr).second.get();
}
osg::Material* poolMaterial = get(index);
// Create final material.
osg::Material* material = dynamic_cast<osg::Material*>(poolMaterial->clone(osg::CopyOp::SHALLOW_COPY));
osg::Vec4 materialPaletteAmbient = poolMaterial->getAmbient(osg::Material::FRONT);
osg::Vec4 materialPaletteDiffuse = poolMaterial->getDiffuse(osg::Material::FRONT);
material->setAmbient(osg::Material::FRONT_AND_BACK, finalColor(materialPaletteAmbient, faceColor));
material->setDiffuse(osg::Material::FRONT_AND_BACK, finalColor(materialPaletteDiffuse, faceColor));
material->setAlpha(osg::Material::FRONT_AND_BACK, materialPaletteAmbient.a()*faceColor.a());
// Set final material so it can be reused.
_finalMaterialMap[materialParam] = material;
return material;
}

View File

@@ -0,0 +1,214 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_POOLS_H
#define FLT_POOLS_H 1
#include <vector>
#include <map>
// need to replace this... and associated istrstream as its deprecated
#include <strstream>
#include <osg/Vec4>
#include <osg/StateSet>
#include <osg/Material>
#include <osg/Program>
#include "types.h"
namespace flt {
class VertexPool : public osg::Referenced, public std::istrstream
{
const char* _buffer;
public:
explicit VertexPool(std::streamsize count) :
std::istrstream(_buffer=new char[count],count) {}
protected:
virtual ~VertexPool()
{
if (_buffer) delete [] _buffer;
}
};
class ColorPool : public osg::Referenced , public std::vector<osg::Vec4>
{
public:
explicit ColorPool(bool old,int size) :
std::vector<osg::Vec4>(size),
_old(old) {}
osg::Vec4 getColor(int indexIntensity) const;
protected:
virtual ~ColorPool() {}
bool _old; // true if version <= 13
};
class TexturePool : public osg::Referenced , public std::map<int,osg::ref_ptr<osg::StateSet> >
{
public:
TexturePool() {}
osg::StateSet* get(int index)
{
iterator itr = find(index);
if (itr != end())
return (*itr).second.get();
return NULL;
}
protected:
virtual ~TexturePool() {}
};
class MaterialPool : public osg::Referenced , public std::map<int,osg::ref_ptr<osg::Material> >
{
public:
MaterialPool();
// Get material, return default material if not found in palette.
osg::Material* get(int index);
// Get or create material based on
// index: face material index
// color: face color with alpha set to 1-face transparency.
osg::Material* getOrCreateMaterial(int index, const osg::Vec4& faceColor);
protected:
virtual ~MaterialPool() {}
osg::ref_ptr<osg::Material> _defaultMaterial;
struct MaterialParameters
{
int index; // face index to material pool
osg::Vec4 color; // face color with alpha set to 1-face transparency.
MaterialParameters():
index(-1) {}
MaterialParameters(int i, const osg::Vec4& c):
index(i),
color(c) {}
bool operator < (const MaterialParameters& rhs) const
{
if (index < rhs.index) return true;
else if (index > rhs.index) return false;
else return (color < rhs.color);
}
};
// Material from palette combined with face color stored here for reuse.
typedef std::map<MaterialParameters,osg::ref_ptr<osg::Material> > FinalMaterialMap;
FinalMaterialMap _finalMaterialMap;
};
struct LPAppearance : public osg::Referenced
{
std::string name;
int32 index;
int16 materialCode;
int16 featureID;
osg::Vec4f backColor;
int32 displayMode;
float32 intensityFront;
float32 intensityBack;
float32 minDefocus;
float32 maxDefocus;
int32 fadingMode;
int32 fogPunchMode;
int32 directionalMode;
int32 rangeMode;
float32 minPixelSize;
float32 maxPixelSize;
float32 actualPixelSize;
float32 transparentFalloffPixelSize;
float32 transparentFalloffExponent;
float32 transparentFalloffScalar;
float32 transparentFalloffClamp;
float32 fogScalar;
float32 fogIntensity;
float32 sizeDifferenceThreshold;
int32 directionality;
float32 horizontalLobeAngle;
float32 verticalLobeAngle;
float32 lobeRollAngle;
float32 directionalFalloffExponent;
float32 directionalAmbientIntensity;
float32 significance;
uint32 flags;
float32 visibilityRange;
float32 fadeRangeRatio;
float32 fadeInDuration;
float32 fadeOutDuration;
float32 LODRangeRatio;
float32 LODScale;
int32 texturePatternIndex;
};
class LightPointAppearancePool : public osg::Referenced , public std::map<int,osg::ref_ptr<LPAppearance> >
{
public:
LightPointAppearancePool() {}
LPAppearance* get(int index)
{
iterator itr = find(index);
if (itr != end())
return (*itr).second.get();
return NULL;
}
protected:
virtual ~LightPointAppearancePool() {}
};
class ShaderPool : public osg::Referenced , public std::map<int,osg::ref_ptr<osg::Program> >
{
public:
ShaderPool() {}
osg::Program* get(int index)
{
iterator itr = find(index);
if (itr != end())
return (*itr).second.get();
return NULL;
}
protected:
virtual ~ShaderPool() {}
};
} // end namespace
#endif

View File

@@ -0,0 +1,747 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osg/Notify>
#include <osg/ShadeModel>
#include <osg/ProxyNode>
#include <osg/Sequence>
#include <osg/LOD>
#include <osgDB/FileUtils>
#include <osgSim/DOFTransform>
#include <osgSim/MultiSwitch>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
/** Header
*/
class Header : public PrimaryRecord
{
static const unsigned int SAVE_VERTEX_NORMALS_BIT = 0x80000000u >> 0;
static const unsigned int PACKED_COLOR_MODE_BIT = 0x80000000u >> 1;
static const unsigned int CAD_VIEW_MODE_BIT = 0x80000000u >> 2;
osg::ref_ptr<osg::Group> _header;
public:
Header() {}
META_Record(Header)
META_setID(_header)
META_setComment(_header)
// META_setMatrix(_header)
META_setMultitexture(_header)
META_addChild(_header)
protected:
virtual ~Header() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
osg::notify(osg::DEBUG_INFO) << "ID: " << id << std::endl;
uint32 format = in.readUInt32();
osg::notify(osg::DEBUG_INFO) << "Format: " << format << std::endl;
document._version = format;
uint32 revision = in.readUInt32();
std::string revisionTime = in.readString(32);
osg::notify(osg::INFO) << "Last revision: " << revisionTime << std::endl;
in.forward(4*2);
// Flight v.11 & 12 use integer coordinates
int16 multDivUnits = in.readInt16(); // Units multiplier/divisor
uint8 units = in.readUInt8(); // 0=Meters 1=Kilometers 4=Feet 5=Inches 8=Nautical miles
uint8 textureWhite = in.readUInt8();
uint32 flags = in.readUInt32();
if (document.getDoUnitsConversion())
document._unitScale = unitsToMeters((CoordUnits)units) / unitsToMeters(document.getDesiredUnits());
if (document._version < VERSION_13)
{
if (multDivUnits >= 0)
document._unitScale *= (double)multDivUnits;
else
document._unitScale /= (double)(-multDivUnits);
}
_header = new osg::Group;
_header->setName(id);
document.setHeaderNode(_header.get());
}
};
RegisterRecordProxy<Header> g_Header(HEADER_OP);
/** Object
*/
class Object : public PrimaryRecord
{
static const unsigned int HIDE_IN_DAYLIGHT = 0x80000000u >> 0;
static const unsigned int HIDE_AT_DUSK = 0x80000000u >> 1;
static const unsigned int HIDE_AT_NIGHT = 0x80000000u >> 2;
static const unsigned int NO_ILLUMINATION = 0x80000000u >> 3;
static const unsigned int FLAT_SHADED = 0x80000000u >> 4;
static const unsigned int SHADOW_OBJECT = 0x80000000u >> 5;
osg::ref_ptr<osg::Group> _object;
public:
Object() {}
META_Record(Object)
META_setID(_object)
META_setComment(_object)
META_setMatrix(_object)
META_setMultitexture(_object)
META_addChild(_object)
protected:
virtual ~Object() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
uint32 flags = in.readUInt32();
_object = new osg::Group;
_object->setName(id);
// Flat shaded?
if (flags & FLAT_SHADED)
{
osg::ShadeModel* shademodel = new osg::ShadeModel;
shademodel->setMode(osg::ShadeModel::FLAT);
_object->getOrCreateStateSet()->setAttribute(shademodel);
}
if (_parent.valid())
_parent->addChild(*_object);
}
};
RegisterRecordProxy<Object> g_Object(OBJECT_OP);
/** Group
*/
class Group : public PrimaryRecord
{
static const unsigned int FORWARD_ANIM = 0x80000000u >> 1;
static const unsigned int SWING_ANIM = 0x80000000u >> 2;
static const unsigned int BOUND_BOX_FOLLOW = 0x80000000u >> 3;
static const unsigned int FREEZE_BOUND_BOX = 0x80000000u >> 4;
static const unsigned int DEFAULT_PARENT = 0x80000000u >> 5;
static const unsigned int BACKWARD_ANIM = 0x80000000u >> 6;
osg::ref_ptr<osg::Group> _group;
public:
Group() {}
META_Record(Group)
META_setID(_group)
META_setComment(_group)
META_setMatrix(_group)
META_setMultitexture(_group)
META_addChild(_group)
protected:
virtual ~Group() {}
void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
osg::notify(osg::DEBUG_INFO) << "ID: " << id << std::endl;
int16 relativePriority = in.readInt16();
in.forward(2);
uint32 flags = in.readUInt32();
uint16 specialId0 = in.readUInt16();
uint16 specialId1 = in.readUInt16();
uint16 significance = in.readUInt16();
int8 layer = in.readInt8();
in.forward(5);
uint32 loopCount = in.readUInt32();
float32 loopDuration = in.readFloat32();
float32 lastFrameDuration = in.readFloat32();
// Check for forward animation (sequence)
bool forwardAnim = (flags & FORWARD_ANIM) != 0;
// For versions prior to 15.8, the swing bit can be set independently
// of the animation bit. This implies forward animation (with swing)
if ((document.version() < VERSION_15_8) && (flags & SWING_ANIM))
forwardAnim = true;
// OpenFlight 15.8 adds backwards animations
const bool backwardAnim = ( (document.version() >= VERSION_15_8) &&
((flags & BACKWARD_ANIM) != 0) );
if (forwardAnim || backwardAnim)
{
osg::ref_ptr<osg::Sequence> sequence = new osg::Sequence;
// Regardless of forwards or backwards, animation could have swing bit set
const osg::Sequence::LoopMode loopMode = ((flags & SWING_ANIM) == 0) ?
osg::Sequence::LOOP : osg::Sequence::SWING;
if (forwardAnim)
sequence->setInterval(loopMode, 0, -1);
else
sequence->setInterval(loopMode, -1, 0);
float speed=0.1f;
sequence->setDuration(speed);
sequence->setMode(osg::Sequence::START);
_group = sequence.get();
}
else
{
_group = new osg::Group;
}
_group->setName(id);
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_group);
}
};
RegisterRecordProxy<Group> g_Group(GROUP_OP);
/** DegreeOfFreedom
*/
class DegreeOfFreedom : public PrimaryRecord
{
// Flags
static const unsigned long LIMIT_TRANSLATION_X = 0x80000000u >> 0;
static const unsigned long LIMIT_TRANSLATION_Y = 0x80000000u >> 1;
static const unsigned long LIMIT_TRANSLATION_Z = 0x80000000u >> 2;
static const unsigned long LIMIT_PITCH = 0x80000000u >> 3;
static const unsigned long LIMIT_ROLL = 0x80000000u >> 4;
static const unsigned long LIMIT_YAW = 0x80000000u >> 5;
static const unsigned long LIMIT_SCALE_X = 0x80000000u >> 6;
static const unsigned long LIMIT_SCALE_Y = 0x80000000u >> 7;
static const unsigned long LIMIT_SCALE_Z = 0x80000000u >> 8;
struct Range
{
float64 min; // Minimum value with respect to the local coord system
float64 max; // Maximum value with respect to the local coordsystem
float64 current; // Current value with respect to the local coord system
float64 increment; // Increment
};
osg::ref_ptr<osgSim::DOFTransform> _dof;
public:
DegreeOfFreedom():
_dof(new osgSim::DOFTransform) {}
META_Record(DegreeOfFreedom)
META_setID(_dof)
META_setComment(_dof)
META_setMatrix(_dof)
META_setMultitexture(_dof)
META_addChild(_dof)
protected:
virtual ~DegreeOfFreedom() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
in.forward(4); // Reserved
osg::Vec3d localOrigin = in.readVec3d();
osg::Vec3d pointOnXAxis = in.readVec3d();
osg::Vec3d pointInXYPlane = in.readVec3d();
Range rangeZ = readRange(in); // Legal z values with respect to the local coord system
Range rangeY = readRange(in); // Legal y values with respect to the local coord system
Range rangeX = readRange(in); // Legal x values with respect to the local coord system
Range rangePitch = readRange(in); // Legal pitch values (rotation about the x-axis)
Range rangeRoll = readRange(in); // Legal roll values( rotation about the y-axis)
Range rangeYaw = readRange(in); // Legal yaw values (rotation about the z-axis)
Range rangeScaleZ = readRange(in); // Legal z scale values (about local origin)
Range rangeScaleY = readRange(in); // Legal y scale values about local origin)
Range rangeScaleX = readRange(in); // Legal x scale values (about local origin)
uint32 flags = in.readUInt32(); // Flags, bits from left to right (see OF doc)
// out of range check, required for racecar.flt (Creator Gallery)
if (!valid(localOrigin))
localOrigin = osg::Vec3d(0,0,0);
if (!valid(pointOnXAxis))
pointOnXAxis = osg::X_AXIS;
if (!valid(pointInXYPlane))
pointInXYPlane = osg::Y_AXIS;
_dof->setName(id);
//tranlsations:
_dof->setMinTranslate(osg::Vec3(rangeX.min,rangeY.min,rangeZ.min)*document.unitScale());
_dof->setMaxTranslate(osg::Vec3(rangeX.max,rangeY.max,rangeZ.max)*document.unitScale());
_dof->setCurrentTranslate(osg::Vec3(rangeX.current,rangeY.current,rangeZ.current)*document.unitScale());
_dof->setIncrementTranslate(osg::Vec3(rangeX.increment,rangeY.increment,rangeZ.increment)*document.unitScale());
//rotations:
_dof->setMinHPR(osg::Vec3(osg::inDegrees(rangeYaw.min),osg::inDegrees(rangePitch.min),osg::inDegrees(rangeRoll.min)));
_dof->setMaxHPR(osg::Vec3(osg::inDegrees(rangeYaw.max),osg::inDegrees(rangePitch.max),osg::inDegrees(rangeRoll.max)));
_dof->setCurrentHPR(osg::Vec3(osg::inDegrees(rangeYaw.current),osg::inDegrees(rangePitch.current),osg::inDegrees(rangeRoll.current)));
_dof->setIncrementHPR(osg::Vec3(osg::inDegrees(rangeYaw.increment),osg::inDegrees(rangePitch.increment),osg::inDegrees(rangeRoll.increment)));
//scales:
_dof->setMinScale(osg::Vec3(rangeScaleX.min,rangeScaleY.min,rangeScaleZ.min));
_dof->setMaxScale(osg::Vec3(rangeScaleX.max,rangeScaleY.max,rangeScaleZ.max));
_dof->setCurrentScale(osg::Vec3(rangeScaleX.current,rangeScaleY.current,rangeScaleZ.current));
_dof->setIncrementScale(osg::Vec3(rangeScaleX.increment,rangeScaleY.increment,rangeScaleZ.increment));
// compute axis.
osg::Vec3 xAxis = pointOnXAxis - localOrigin;
osg::Vec3 xyPlaneVector = pointInXYPlane - localOrigin;
osg::Vec3 zAxis = xAxis ^ xyPlaneVector;
osg::Vec3 yAxis = zAxis ^ xAxis;
// normalize
xAxis.normalize();
yAxis.normalize();
zAxis.normalize();
// scale origin
osg::Vec3 origin = localOrigin * document.unitScale();
// create putmatrix
osg::Matrix inv_putmat(xAxis.x(), xAxis.y(), xAxis.z(), 0.0,
yAxis.x(), yAxis.y(), yAxis.z(), 0.0,
zAxis.x(), zAxis.y(), zAxis.z(), 0.0,
origin.x(), origin.y(), origin.z(), 1.0);
_dof->setInversePutMatrix(inv_putmat);
_dof->setPutMatrix(osg::Matrix::inverse(inv_putmat));
_dof->setLimitationFlags(flags);
_dof->setAnimationOn(document.getDefaultDOFAnimationState());
// _dof->setHPRMultOrder(osgSim::DOFTransform::HPR);
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_dof);
}
Range readRange(RecordInputStream& in) const
{
Range range;
range.min = in.readFloat64();
range.max = in.readFloat64();
range.current = in.readFloat64();
range.increment = in.readFloat64();
// Extend valid range (See Creator help on DOF).
if (range.current < range.min) range.min = range.current;
if (range.current > range.max) range.max = range.current;
const float64 epsilon = 1.0e-7;
if (fabs(range.max-range.min) < epsilon)
range.increment = 0;
return range;
}
bool valid(const osg::Vec3d& v) const
{
const osg::Vec3d bad(-1.0e8,-1.0e8,-1.0e8);
const float64 epsilon = 1.0e-7;
return (fabs(v.x()-bad.x()) > epsilon) ||
(fabs(v.y()-bad.y()) > epsilon) ||
(fabs(v.z()-bad.z()) > epsilon);
}
};
RegisterRecordProxy<DegreeOfFreedom> g_DegreeOfFreedom(DOF_OP);
/** LevelOfDetail - To recreate the LevelOfDetail record in OSG we have to create a LOD node with one Group node under it.
* OSG representation Children of the LevelOfDetail record will be added to
*/
class LevelOfDetail : public PrimaryRecord
{
osg::ref_ptr<osg::LOD> _lod;
osg::ref_ptr<osg::Group> _impChild0;
public:
LevelOfDetail() {}
META_Record(LevelOfDetail)
META_setID(_lod)
META_setComment(_lod)
META_setMatrix(_lod)
META_setMultitexture(_lod)
META_addChild(_impChild0)
protected:
virtual ~LevelOfDetail() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
in.forward(4);
float64 switchInDistance = in.readFloat64();
float64 switchOutDistance = in.readFloat64();
int16 specialEffectID1 = in.readInt16();
int16 specialEffectID2 = in.readInt16();
uint32 flags = in.readUInt32();
osg::Vec3d center = in.readVec3d();
_lod = new osg::LOD;
_lod->setName(id);
_lod->setCenter(center*document.unitScale());
_impChild0 = new osg::Group;
_impChild0->setName("LOD child0");
// Add child to lod.
_lod->addChild(_impChild0.get(),
(float)switchOutDistance * document.unitScale(),
(float)switchInDistance * document.unitScale());
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_lod);
}
};
RegisterRecordProxy<LevelOfDetail> g_LevelOfDetail(LOD_OP);
/** OldLevelOfDetail
*/
class OldLevelOfDetail : public PrimaryRecord
{
osg::ref_ptr<osg::LOD> _lod;
osg::ref_ptr<osg::Group> _impChild0;
public:
OldLevelOfDetail() {}
META_Record(OldLevelOfDetail)
META_setID(_lod)
META_setComment(_lod)
META_setMatrix(_lod)
META_setMultitexture(_lod)
META_addChild(_impChild0)
protected:
virtual ~OldLevelOfDetail() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
uint32 switchInDistance = in.readUInt32();
uint32 switchOutDistance = in.readUInt32();
int16 specialEffectID1 = in.readInt16();
int16 specialEffectID2 = in.readInt16();
uint32 flags = in.readUInt32();
osg::Vec3 center;
center.x() = (float)in.readInt32();
center.y() = (float)in.readInt32();
center.z() = (float)in.readInt32();
_lod = new osg::LOD;
_lod->setName(id);
_lod->setCenter(center*document.unitScale());
_lod->setRange(0, (float)switchOutDistance * document.unitScale(),
(float)switchInDistance * document.unitScale());
// Add child to lod.
_impChild0 = new osg::Group;
_lod->addChild(_impChild0.get());
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_lod);
}
};
RegisterRecordProxy<OldLevelOfDetail> g_OldLevelOfDetail(OLD_LOD_OP);
/** Switch
*/
class Switch : public PrimaryRecord
{
uint32 _currentMask;
uint32 _numberOfMasks;
uint32 _wordsInMask;
std::vector<uint32> _masks;
osg::ref_ptr<osgSim::MultiSwitch> _multiSwitch;
public:
Switch() {}
META_Record(Switch)
META_setID(_multiSwitch)
META_setComment(_multiSwitch)
META_setMatrix(_multiSwitch)
META_setMultitexture(_multiSwitch)
virtual void addChild(osg::Node& child)
{
if (_multiSwitch.valid())
{
unsigned int nChild = _multiSwitch->getNumChildren();
for (unsigned int nMask=0; nMask<_numberOfMasks; ++nMask)
{
// test if this child is active in the current mask (itMask)
unsigned int nMaskBit = nChild % 32;
unsigned int nMaskWord = nMask * _wordsInMask + nChild / 32;
_multiSwitch->setValue(nMask, nChild, (_masks[nMaskWord] & (uint32(1) << nMaskBit))!=0 );
}
_multiSwitch->addChild(&child);
}
}
protected:
virtual ~Switch() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
in.forward(4);
_currentMask = in.readUInt32();
_numberOfMasks = in.readUInt32();
_wordsInMask = in.readUInt32();
_multiSwitch = new osgSim::MultiSwitch;
_multiSwitch->setName(id);
/* Example:
| word #0 || word #1 || word #2 | <- Mask #0
| word #0 || word #1 || word #2 | <- Mask #1
In this example numberOfMasks=2 and wordsInMask=3, currentMask can be 0 or 1.
*/
for (unsigned int n=0; n<_numberOfMasks*_wordsInMask; n++)
{
uint32 maskWord = in.readUInt32();
_masks.push_back(maskWord);
}
_multiSwitch->setActiveSwitchSet(_currentMask);
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_multiSwitch);
}
};
RegisterRecordProxy<Switch> g_Switch(SWITCH_OP);
/** ExternalReference
*/
class ExternalReference : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _external;
public:
ExternalReference() {}
META_Record(ExternalReference)
META_setID(_external)
META_setComment(_external)
META_setMatrix(_external)
META_setMultitexture(_external)
META_addChild(_external)
protected:
virtual ~ExternalReference() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string strFile = in.readString(200);
//Path for Nested external references
const osgDB::ReaderWriter::Options *options = document.getOptions();
std::string filename = osgDB::findDataFile(strFile, options);
if (filename.empty())
{
osg::notify(osg::WARN) << "Can't find external " << strFile << std::endl;
return;
}
_external = new osg::Group;
_external->setName(strFile);
Registry::instance()->addExternal(filename, _external.get());
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_external);
}
};
RegisterRecordProxy<ExternalReference> g_ExternalReference(EXTERNAL_REFERENCE_OP);
/** InstanceDefinition
*/
class InstanceDefinition : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _instanceDefinition;
public:
InstanceDefinition() {}
META_Record(InstanceDefinition)
META_setID(_instanceDefinition)
META_setComment(_instanceDefinition)
META_setMultitexture(_instanceDefinition)
META_addChild(_instanceDefinition)
virtual void setMatrix(osg::Matrix& matrix)
{
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(matrix);
transform->setDataVariance(osg::Object::STATIC);
transform->addChild(_instanceDefinition.get());
_instanceDefinition = transform.get();
}
protected:
virtual ~InstanceDefinition() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
in.forward(2);
uint16 number = in.readUInt16();
_instanceDefinition = new osg::Group;
// Add to instance definition table.
document.setInstanceDefinition(number,_instanceDefinition.get());
}
};
RegisterRecordProxy<InstanceDefinition> g_InstanceDefinition(INSTANCE_DEFINITION_OP);
/** InstanceReference
* The InstanceReference is a leaf record.
*/
class InstanceReference : public PrimaryRecord
{
public:
InstanceReference() {}
META_Record(InstanceReference)
protected:
virtual ~InstanceReference() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
in.forward(2);
uint16 number = in.readUInt16();
// Get definition.
osg::Node* instance = document.getInstanceDefinition(number);
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*instance);
}
};
RegisterRecordProxy<InstanceReference> g_InstanceReference(INSTANCE_REFERENCE_OP);
/** Extension
*/
class Extension : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _extension;
public:
Extension() {}
META_Record(Extension)
META_setID(_extension)
META_setComment(_extension)
META_setMatrix(_extension)
META_setMultitexture(_extension)
META_addChild(_extension)
protected:
virtual ~Extension() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
std::string siteId = in.readString(8);
in.forward(1);
_extension = new osg::Group;
_extension->setName(id);
// Add this implementation to parent implementation.
if (_parent.valid())
_parent->addChild(*_extension);
}
};
RegisterRecordProxy<Extension> g_Extension(EXTENSION_OP);
} // end namespace

View File

@@ -0,0 +1,177 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osg/Notify>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <osg/StateSet>
#include <osg/GL>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include "AttrData.h"
#include "DataInputStream.h"
using namespace osg;
using namespace osgDB;
using namespace flt;
class ReaderWriterATTR : public osgDB::ReaderWriter
{
public:
virtual const char* className() const { return "ATTR Image Attribute Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension) const
{
return equalCaseInsensitive(extension,"attr");
}
virtual ReadResult readObject(const std::string& fileName, const ReaderWriter::Options*) const;
};
ReaderWriter::ReadResult ReaderWriterATTR::readObject(const std::string& file, const ReaderWriter::Options* options) const
{
using std::ios;
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
std::ifstream fin(fileName.c_str(), ios::in | ios::binary);
if ( fin.fail())
return ReadResult::ERROR_IN_READING_FILE;
flt::DataInputStream in(&fin);
AttrData* attr = new AttrData;
try
{
attr->texels_u = in.readInt32();
attr->textel_v = in.readInt32();
attr->direction_u = in.readInt32();
attr->direction_v = in.readInt32();
attr->x_up = in.readInt32();
attr->y_up = in.readInt32();
attr->fileFormat = in.readInt32();
attr->minFilterMode = in.readInt32();
attr->magFilterMode = in.readInt32();
attr->wrapMode = in.readInt32();
attr->wrapMode_u = in.readInt32();
if ((attr->wrapMode_u != AttrData::WRAP_CLAMP) && ((attr->wrapMode_u != AttrData::WRAP_REPEAT)))
attr->wrapMode_u = attr->wrapMode;
attr->wrapMode_v = in.readInt32();
if ((attr->wrapMode_v != AttrData::WRAP_CLAMP) && ((attr->wrapMode_v != AttrData::WRAP_REPEAT)))
attr->wrapMode_v = attr->wrapMode;
attr->modifyFlag = in.readInt32();
attr->pivot_x = in.readInt32();
attr->pivot_y = in.readInt32();
// v11 ends here
// if (in.eof() || (_flt_version <= 11)) return true;
#if 1
attr->texEnvMode = in.readInt32();
attr->intensityAsAlpha = in.readInt32();
in.forward(4*8);
attr->size_u = in.readFloat64();
attr->size_v = in.readFloat64();
attr->originCode = in.readInt32();
attr->kernelVersion = in.readInt32();
attr->intFormat = in.readInt32();
attr->extFormat = in.readInt32();
attr->useMips = in.readInt32();
for (int n=0; n<8; n++)
attr->_mips[n] = in.readFloat32();
attr->useLodScale = in.readInt32();
attr->lod0 = in.readFloat32();
attr->scale0 = in.readFloat32();
attr->lod1 = in.readFloat32();
attr->scale1 = in.readFloat32();
attr->lod2 = in.readFloat32();
attr->scale2 = in.readFloat32();
attr->lod3 = in.readFloat32();
attr->scale3 = in.readFloat32();
attr->lod4 = in.readFloat32();
attr->scale4 = in.readFloat32();
attr->lod5 = in.readFloat32();
attr->scale5 = in.readFloat32();
attr->lod6 = in.readFloat32();
attr->scale6 = in.readFloat32();
attr->lod7 = in.readFloat32();
attr->scale7 = in.readFloat32();
attr->clamp = in.readFloat32();
attr->magFilterAlpha = in.readInt32();
attr->magFilterColor = in.readInt32();
in.forward(4);
in.forward(4*8);
attr->lambertMeridian = in.readFloat64();
attr->lambertUpperLat = in.readFloat64();
attr->lambertlowerLat = in.readFloat64();
in.forward(8);
in.forward(4*5);
attr->useDetail = in.readInt32( );
attr->txDetail_j = in.readInt32();
attr->txDetail_k = in.readInt32();
attr->txDetail_m = in.readInt32();
attr->txDetail_n = in.readInt32();
attr->txDetail_s = in.readInt32( );
attr->useTile = in.readInt32();
attr->txTile_ll_u= in.readFloat32();
attr->txTile_ll_v = in.readFloat32();
attr->txTile_ur_u = in.readFloat32();
attr->txTile_ur_v = in.readFloat32();
attr->projection = in.readInt32();
attr->earthModel = in.readInt32();
in.forward(4);
attr->utmZone = in.readInt32();
attr->imageOrigin = in.readInt32();
attr->geoUnits = in.readInt32();
in.forward(4);
in.forward(4);
attr->hemisphere = in.readInt32();
in.forward(4);
in.forward(4);
in.forward(149);
attr->comments = in.readString(512);
// v12 ends here
// if (in.eof() || (_flt_version <= 12)) return true;
in.forward(13*4);
attr->attrVersion = in.readInt32();
attr->controlPoints = in.readInt32();
in.forward(4);
#endif
}
catch(...)
{
if (!fin.eof())
{
throw;
}
}
fin.close();
return attr;
}
// now register with Registry to instantiate the above
// reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterATTR> g_readerWriter_ATTR_Proxy;

View File

@@ -0,0 +1,187 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <stdexcept>
#include <osg/Notify>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/ReentrantMutex>
#include <osgSim/OpenFlightOptimizer>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
#define SERIALIZER() OpenThreads::ScopedLock<osgDB::ReentrantMutex> lock(_serializerMutex)
using namespace flt;
using namespace osg;
using namespace osgDB;
class FLTReaderWriter : public ReaderWriter
{
public:
virtual const char* className() const { return "FLT Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension) const
{
return equalCaseInsensitive(extension,"flt");
}
virtual ReadResult readObject(const std::string& file, const Options* options) const
{
return readNode(file, options);
}
virtual ReadResult readNode(const std::string& file, const Options* options) const
{
SERIALIZER();
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
// local_opt->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
return readNode(istream,local_opt.get());
}
virtual ReadResult readObject(std::istream& fin, const Options* options) const
{
return readNode(fin, options);
}
virtual ReadResult readNode(std::istream& fin, const Options* options) const
{
try
{
Document document;
document.setOptions(options);
// option string
if (options)
{
document.setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")==std::string::npos);
osg::notify(osg::DEBUG_INFO) << "FltFile.getUseTextureAlphaForTransparancyBinning()=" << document.getUseTextureAlphaForTransparancyBinning() << std::endl;
document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified.o
osg::notify(osg::DEBUG_INFO) << "FltFile.getDoUnitsConversion()=" << document.getDoUnitsConversion() << std::endl;
if (document.getDoUnitsConversion())
{
if (options->getOptionString().find("convertToFeet")!=std::string::npos)
document.setDesiredUnits(FEET);
else if (options->getOptionString().find("convertToInches")!=std::string::npos)
document.setDesiredUnits(INCHES);
else if (options->getOptionString().find("convertToMeters")!=std::string::npos)
document.setDesiredUnits(METERS);
else if (options->getOptionString().find("convertToKilometers")!=std::string::npos)
document.setDesiredUnits(KILOMETERS);
else if (options->getOptionString().find("convertToNauticalMiles")!=std::string::npos)
document.setDesiredUnits(NAUTICAL_MILES);
}
}
{
// read records
flt::RecordInputStream recordStream(&fin);
while (recordStream().good() && !document.done())
{
recordStream.readRecord(document);
}
}
{
// optimize
osgFlightUtil::Optimizer optimizer;
optimizer.optimize(document.getHeaderNode());
}
readExternals(options);
return document.getHeaderNode();
}
catch (std::exception &e)
{
osg::notify(osg::NOTICE) << "Error reading file: " << e.what() << std::endl;
return ReadResult::FILE_NOT_HANDLED;
}
catch (...)
{
return ReadResult::FILE_NOT_HANDLED;
}
}
virtual WriteResult writeObject(const Object& object,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
{
const Node* node = dynamic_cast<const Node*>(&object);
if (node) return writeNode( *node, fileName, options );
return WriteResult::FILE_NOT_HANDLED;
}
virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
{
std::string ext = getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
if(local_opt->getDatabasePathList().empty())
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
WriteResult result = writeNode(node, fout, local_opt.get());
fout.close();
return result;
}
virtual WriteResult writeObject(const Object& object,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
{
const Node* node = dynamic_cast<const Node*>(&object);
if (node) return writeNode( *node, fout, options );
return WriteResult::FILE_NOT_HANDLED;
}
virtual WriteResult writeNode(const Node& node,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
{
return WriteResult::FILE_NOT_HANDLED;
}
protected:
void readExternals(const Options* options) const
{
flt::Registry::ExternalQueue& eq = flt::Registry::instance()->getExternalQueue();
while (!eq.empty())
{
std::string extfilename = eq.front().first;
osg::ref_ptr<osg::Group> external = eq.front().second;
eq.pop();
if (external.valid())
{
osg::Node* extmodel = osgDB::readNodeFile(extfilename,options);
external->addChild(extmodel);
}
}
}
mutable osgDB::ReentrantMutex _serializerMutex;
};
// now register with Registry to instantiate the above
// reader/writer.
RegisterReaderWriterProxy<FLTReaderWriter> g_FLTReaderWriterProxy;

View File

@@ -0,0 +1,138 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <stdexcept>
#include <osg/Texture2D>
#include <osg/MatrixTransform>
#include "Record.h"
#include "Document.h"
using namespace flt;
Record::Record()
{
}
void Record::setParent(PrimaryRecord* parent)
{
_parent = parent;
}
//PrimaryRecord& Record::parent()
//{
// if (!_parent)
// throw std::runtime_error("Record::parent(): invalid pointer to parent exception.");
//
// return *_parent;
//}
void Record::read(RecordInputStream& in, Document& document)
{
setParent(document.getCurrentPrimaryRecord());
// Read record body.
readRecord(in,document);
}
void Record::readRecord(RecordInputStream& in, Document& document)
{
}
PrimaryRecord::PrimaryRecord() :
_numberOfReplications(0)
{
}
void PrimaryRecord::read(RecordInputStream& in, Document& document)
{
setParent(document.getTopOfLevelStack());
// Update primary record.
document.setCurrentPrimaryRecord(this);
// Read record body.
readRecord(in,document);
}
///////////////////////////////////////////////////////////////////////////////////
// Helper methods
// Insert matrix-tranform above node.
// Return transform.
osg::ref_ptr<osg::MatrixTransform> flt::insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix)
{
osg::ref_ptr<osg::Node> ref = &node;
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(matrix);
transform->setDataVariance(osg::Object::STATIC);
// Replace parent
osg::Node::ParentList parents = node.getParents();
for (osg::Node::ParentList::iterator itr=parents.begin();
itr!=parents.end();
++itr)
{
(*itr)->replaceChild(&node,transform.get());
}
// Make primary a child of matrix transform.
transform->addChild(&node);
return transform;
}
///////////////////////////////////////////////////////////////////////////////////
osg::Vec3Array* flt::getOrCreateVertexArray(osg::Geometry& geometry)
{
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry.getVertexArray());
if (!vertices)
{
vertices = new osg::Vec3Array;
geometry.setVertexArray(vertices);
}
return vertices;
}
osg::Vec3Array* flt::getOrCreateNormalArray(osg::Geometry& geometry)
{
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry.getNormalArray());
if (!normals)
{
normals = new osg::Vec3Array;
geometry.setNormalArray(normals);
}
return normals;
}
osg::Vec4Array* flt::getOrCreateColorArray(osg::Geometry& geometry)
{
osg::Vec4Array* colors = dynamic_cast<osg::Vec4Array*>(geometry.getColorArray());
if (!colors)
{
colors = new osg::Vec4Array;
geometry.setColorArray(colors);
}
return colors;
}
osg::Vec2Array* flt::getOrCreateTextureArray(osg::Geometry& geometry, int unit)
{
osg::Vec2Array* UVs = dynamic_cast<osg::Vec2Array*>(geometry.getTexCoordArray(unit));
if (!UVs)
{
UVs = new osg::Vec2Array;
geometry.setTexCoordArray(unit,UVs);
}
return UVs;
}

View File

@@ -0,0 +1,114 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_RECORD_H
#define FLT_RECORD_H 1
#include <stdexcept>
#include <string>
#include <osg/Array>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Group>
#include <osg/MatrixTransform>
#include "Vertex.h"
namespace flt
{
class RecordInputStream;
class Document;
class PrimaryRecord;
class Matrix;
#define META_Record(name) \
virtual flt::Record* cloneType() const { return new name (); } \
virtual bool isSameKindAs(const flt::Record* rec) const { return dynamic_cast<const name *>(rec)!=NULL; }
#define META_setID(imp) virtual void setID(const std::string& id) { if (imp.valid()) imp->setName(id); }
#define META_setComment(imp) virtual void setComment(const std::string& id) { if (imp.valid()) imp->addDescription(id); }
#define META_setMatrix(imp) virtual void setMatrix(osg::Matrix& matrix) { if (imp.valid()) insertMatrixTransform(*imp,matrix); }
#define META_setMultitexture(imp) virtual void setMultitexture(osg::StateSet& multitexture) { if (imp.valid()) imp->getOrCreateStateSet()->merge(multitexture); }
#define META_addChild(imp) virtual void addChild(osg::Node& child) { if (imp.valid()) imp->addChild(&child); }
// pure virtual base class
class Record : public osg::Referenced
{
public:
Record();
virtual Record* cloneType() const = 0;
virtual bool isSameKindAs(const Record* rec) const = 0;
virtual void read(RecordInputStream& in, Document& document);
void setParent(PrimaryRecord* parent);
protected:
virtual ~Record() {}
virtual void readRecord(RecordInputStream& in, Document& document);
osg::ref_ptr<PrimaryRecord> _parent;
};
class PrimaryRecord : public Record
{
public:
PrimaryRecord();
virtual void read(RecordInputStream& in, Document& document);
// Ancillary operations
virtual void setID(const std::string& id) {}
virtual void setComment(const std::string& comment) {}
virtual void setMatrix(osg::Matrix& matrix) {}
virtual void setMultitexture(osg::StateSet& multitexture) {}
virtual void addChild(osg::Node& child) {}
virtual void addVertex(Vertex& vertex) {}
virtual void addVertexUV(int layer,const osg::Vec2& uv) {}
virtual void addMorphVertex(Vertex& vertex0, Vertex& vertex100) {}
void setNumberOfReplications(int num) { _numberOfReplications = num; }
protected:
virtual ~PrimaryRecord() {}
int _numberOfReplications;
};
/** DummyRecord -
*/
class DummyRecord : public Record
{
public:
DummyRecord() {}
META_Record(DummyRecord)
protected:
virtual ~DummyRecord() {}
};
osg::ref_ptr<osg::MatrixTransform> insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix);
osg::Vec3Array* getOrCreateVertexArray(osg::Geometry& geometry);
osg::Vec3Array* getOrCreateNormalArray(osg::Geometry& geometry);
osg::Vec4Array* getOrCreateColorArray(osg::Geometry& geometry);
osg::Vec2Array* getOrCreateTextureArray(osg::Geometry& geometry, int unit);
} // end namespace
#endif

View File

@@ -0,0 +1,126 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "opcodes.h"
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
using namespace flt;
using namespace std;
RecordInputStream::RecordInputStream(std::istream* istream):
DataInputStream(istream)
{
#if 0 //def _DEBUG
ios::iostate mask = istream->exceptions();
cout << "ios::badbit=" << ( mask & ios::badbit ) << std::endl;
cout << "ios::failbit=" << ( mask & ios::failbit ) << std::endl;
cout << "ios::eofbit=" << ( mask & ios::eofbit ) << std::endl;
#endif
// dont't throw an exception on failbit
istream->exceptions(istream->exceptions() & ~ios::failbit);
}
RecordInputStream::~RecordInputStream()
{
}
std::istream& RecordInputStream::read(std::istream::char_type *_Str, std::streamsize _Count) const
{
// Bounds check
istream::pos_type pos = _istream->tellg();
if (pos+(istream::pos_type)_Count > _end)
{
_istream->setstate(ios::failbit); // end-of-record (EOR)
return *_istream;
}
return _istream->read(_Str,_Count);
}
bool RecordInputStream::readRecord(Document& document)
{
// Get current read position in stream.
_start = _istream->tellg();
// Get record header without bounds check.
DataInputStream distream(_istream);
uint16 opcode = distream.readUInt16();
uint16 size = distream.readUInt16();
// Correct endian error in Creator v2.5 gallery models.
// Last pop level record in little-endian.
const uint16 LITTLE_ENDIAN_POP_LEVEL_OP = 0x0B00;
if (opcode==LITTLE_ENDIAN_POP_LEVEL_OP)
{
osg::notify(osg::INFO) << "Little endian pop-level record" << std::endl;
opcode=POP_LEVEL_OP;
size=4;
}
// Update end-of-record
_end = _start + (std::istream::pos_type)size;
#if 0
// TODO: Peek at next opcode looking for continuation record.
_istream->seekg(_end, std::ios_base::beg);
if (_istream->fail())
return false;
int16 nextOpcode = readUInt16();
_istream->seekg(_start+(std::istream::pos_type)4, std::ios_base::beg);
if (nextOpcode == CONTINUATION_OP)
{
}
#endif
// Get prototype record
Record* prototype = Registry::instance()->getPrototype((int)opcode);
if (prototype)
{
#if 0 //def _DEBUG
{
for (int i=0; i<document.level(); i++)
cout << " ";
cout << "opcode=" << opcode << " size=" << size;
if (prototype) std::cout << " " << typeid(*prototype).name();
cout << endl;
}
#endif
{
// Create from prototype.
osg::ref_ptr<Record> record = prototype->cloneType();
// Read record
record->read(*this,document);
}
// Clear failbit, it's used for end-of-record testing.
_istream->clear(_istream->rdstate() & ~std::ios::failbit);
}
else // prototype not found
{
osg::notify(osg::WARN) << "Unknown record, opcode=" << opcode << " size=" << size << std::endl;
// Add to registry so we only have to see this error message once.
Registry::instance()->addPrototype(opcode,new DummyRecord);
}
// Move to beginning of next record
_istream->seekg(_end, std::ios_base::beg);
return _istream->good();
}

View File

@@ -0,0 +1,49 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_RECORDINPUTSTREAM_H
#define FLT_RECORDINPUTSTREAM_H 1
#include "Record.h"
#include "DataInputStream.h"
namespace flt {
class Document;
class RecordInputStream : public DataInputStream
{
public:
RecordInputStream(std::istream* istream);
virtual ~RecordInputStream();
// end of record
// bool eor() const;
bool readRecord(Document& data);
inline std::istream::pos_type getStartOfRecord() const { return _start; }
inline std::istream::pos_type getEndOfRecord() const { return _end; }
inline std::streamsize getRecordSize() const { return _end-_start; }
inline std::streamsize getRecordBodySize() const { return getRecordSize()-(std::streamsize)4; }
inline void moveToStartOfRecord() const { _istream->seekg(_start,std::ios_base::beg); }
inline void setEndOfRecord(std::istream::pos_type pos) { _end=pos; }
protected:
virtual std::istream& read(std::istream::char_type *_Str, std::streamsize _Count) const;
// std::istream* _istream;
std::istream::pos_type _start; // start of record
std::istream::pos_type _end; // end of record
};
} // end namespace
#endif

View File

@@ -0,0 +1,47 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osg/Notify>
#include "Registry.h"
using namespace flt;
Registry::Registry()
{
}
Registry::~Registry()
{
}
Registry* Registry::instance()
{
static Registry s_registry;
return &s_registry;
}
void Registry::addPrototype(int opcode, Record* prototype)
{
if (prototype==0L)
{
osg::notify(osg::WARN) << "Not a record." << std::endl;
return;
}
if (_recordProtoMap.find(opcode) != _recordProtoMap.end())
osg::notify(osg::WARN) << "Registry already contains prototype for opcode " << opcode << "." << std::endl;
_recordProtoMap[opcode] = prototype;
}
Record* Registry::getPrototype(int opcode)
{
RecordProtoMap::iterator itr = _recordProtoMap.find(opcode);
if (itr != _recordProtoMap.end())
return (*itr).second.get();
return NULL;
}

View File

@@ -0,0 +1,66 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_REGISTRY_H
#define FLT_REGISTRY_H 1
#include <queue>
#include <osg/ref_ptr>
#include "opcodes.h"
#include "Record.h"
namespace flt {
class Registry : public osg::Referenced
{
public:
~Registry();
static Registry* instance();
// Prototypes
void addPrototype(int opcode, Record* prototype);
Record* getPrototype(int opcode);
// Externals
typedef std::pair<std::string, osg::Group*> ExtNameNodePair;
typedef std::queue<ExtNameNodePair> ExternalQueue;
inline ExternalQueue& getExternalQueue() { return _externalQueue; }
inline void addExternal(const std::string& name, osg::Group* node)
{
_externalQueue.push( ExtNameNodePair(name,node) );
}
protected:
Registry();
typedef std::map<int, osg::ref_ptr<Record> > RecordProtoMap;
RecordProtoMap _recordProtoMap;
ExternalQueue _externalQueue;
};
/** Proxy class for automatic registration of reader/writers with the Registry.*/
template<class T>
class RegisterRecordProxy
{
public:
explicit RegisterRecordProxy(int opcode)
{
Registry::instance()->addPrototype(opcode,new T);
}
~RegisterRecordProxy() {}
};
} // end namespace
#endif

View File

@@ -0,0 +1,23 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "Registry.h"
using namespace flt;
// Prevent "unknown record" message for the following reserved records:
RegisterRecordProxy<DummyRecord> g_Reserved_103(103);
RegisterRecordProxy<DummyRecord> g_Reserved_104(104);
RegisterRecordProxy<DummyRecord> g_Reserved_117(117);
RegisterRecordProxy<DummyRecord> g_Reserved_118(118);
RegisterRecordProxy<DummyRecord> g_Reserved_120(120);
RegisterRecordProxy<DummyRecord> g_Reserved_121(121);
RegisterRecordProxy<DummyRecord> g_Reserved_124(124);
RegisterRecordProxy<DummyRecord> g_Reserved_125(125);

View File

@@ -0,0 +1,121 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osg/Notify>
#include <osg/Group>
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
/** RoadSegment
*/
class RoadSegment : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _roadSegment;
public:
RoadSegment() {}
META_Record(RoadSegment)
META_setID(_roadSegment)
META_setComment(_roadSegment)
META_setMatrix(_roadSegment)
META_setMultitexture(_roadSegment)
META_addChild(_roadSegment)
protected:
virtual ~RoadSegment() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
_roadSegment = new osg::Group;
// Add to parent.
if (_parent.valid())
_parent->addChild(*_roadSegment);
}
};
RegisterRecordProxy<RoadSegment> g_RoadSegment(ROAD_SEGMENT_OP);
/** RoadConstruction
*/
class RoadConstruction : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _roadConstruction;
public:
RoadConstruction() {}
META_Record(RoadConstruction)
META_setID(_roadConstruction)
META_setComment(_roadConstruction)
META_setMatrix(_roadConstruction)
META_setMultitexture(_roadConstruction)
META_addChild(_roadConstruction)
protected:
virtual ~RoadConstruction() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
_roadConstruction = new osg::Group;
// Add to parent.
if (_parent.valid())
_parent->addChild(*_roadConstruction);
}
};
RegisterRecordProxy<RoadConstruction> g_RoadConstruction(ROAD_CONSTRUCTION_OP);
/** RoadPath
*/
class RoadPath : public PrimaryRecord
{
osg::ref_ptr<osg::Group> _roadPath;
public:
RoadPath() {}
META_Record(RoadPath)
META_setID(_roadPath)
META_setComment(_roadPath)
META_setMatrix(_roadPath)
META_setMultitexture(_roadPath)
META_addChild(_roadPath)
protected:
virtual ~RoadPath() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
_roadPath = new osg::Group;
// Add to parent.
if (_parent.valid())
_parent->addChild(*_roadPath);
}
};
RegisterRecordProxy<RoadPath> g_RoadPath(ROAD_PATH_OP);
} // end namespace

View File

@@ -0,0 +1,55 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "Vertex.h"
using namespace flt;
Vertex::Vertex():
_coord(0,0,0),
_color(1,1,1,1),
_normal(0,0,1),
_validColor(false),
_validNormal(false),
_validUV(false)
{
}
Vertex::Vertex(const Vertex& vertex):
_coord(vertex._coord),
_color(vertex._color),
_normal(vertex._normal),
_uv(vertex._uv),
_validColor(vertex._validColor),
_validNormal(vertex._validNormal),
_validUV(vertex._validUV)
{
}
void Vertex::setCoord(osg::Vec3 coord)
{
_coord = coord;
}
void Vertex::setColor(osg::Vec4 color)
{
_color = color;
_validColor = true;
}
void Vertex::setNormal(osg::Vec3 normal)
{
_normal = normal;
_validNormal = true;
}
void Vertex::setUV(osg::Vec2 uv)
{
_uv = uv;
_validUV = true;
}

View File

@@ -0,0 +1,44 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_VERTEX_H
#define FLT_VERTEX_H 1
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
namespace flt {
class Vertex
{
public:
Vertex();
Vertex(const Vertex& vertex);
void setCoord(osg::Vec3 coord);
void setColor(osg::Vec4 color);
void setNormal(osg::Vec3 normal);
void setUV(osg::Vec2 uv);
bool validColor() const { return _validColor; }
bool validNormal() const { return _validNormal; }
bool validUV() const { return _validUV; }
osg::Vec3 _coord;
osg::Vec4 _color;
osg::Vec3 _normal;
osg::Vec2 _uv;
bool _validColor;
bool _validNormal;
bool _validUV;
};
} // end namespace
#endif

View File

@@ -0,0 +1,324 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include "Record.h"
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
namespace flt {
// Color from ColorPool.
osg::Vec4 getColorFromPool(int index, const ColorPool* colorPool)
{
osg::Vec4 color(1,1,1,1);
if (colorPool)
color = colorPool->getColor(index);
return color;
}
// Vertex flags
enum Flags
{
START_HARD_EDGE = (0x8000 >> 0),
NORMAL_FROZEN = (0x8000 >> 1),
NO_COLOR = (0x8000 >> 2),
PACKED_COLOR = (0x8000 >> 3)
};
class VertexC : public Record
{
public:
VertexC() {}
META_Record(VertexC)
virtual ~VertexC() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int colorNameIndex = in.readInt16();
uint16 flags = in.readUInt16();
osg::Vec3d coord = in.readVec3d();
osg::Vec4f packedColor = in.readColor32();
int colorIndex = in.readInt32(-1);
Vertex vertex;
vertex.setCoord(coord*document.unitScale());
// color
if (flags & PACKED_COLOR)
vertex.setColor(packedColor); // Packed color
else if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<VertexC> g_VertexC(VERTEX_C_OP);
class VertexCN : public Record
{
public:
VertexCN() {}
META_Record(VertexCN)
protected:
virtual ~VertexCN() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int colorNameIndex = in.readInt16();
uint16 flags = in.readUInt16();
osg::Vec3d coord = in.readVec3d();
osg::Vec3f normal = in.readVec3f();
osg::Vec4f packedColor = in.readColor32();
int colorIndex = in.readInt32(-1);
Vertex vertex;
vertex.setCoord(coord*document.unitScale());
vertex.setNormal(normal);
// color
if (flags & PACKED_COLOR)
vertex.setColor(packedColor); // Packed color
else if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<VertexCN> g_VertexCN(VERTEX_CN_OP);
class VertexCT : public Record
{
public:
VertexCT() {}
META_Record(VertexCT)
protected:
virtual ~VertexCT() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int colorNameIndex = in.readInt16();
uint16 flags = in.readUInt16();
osg::Vec3d coord = in.readVec3d();
osg::Vec2f uv = in.readVec2f();
osg::Vec4f packedColor = in.readColor32();
int colorIndex = in.readInt32(-1);
Vertex vertex;
vertex.setCoord(coord*document.unitScale());
vertex.setUV(uv);
// color
if (flags & PACKED_COLOR)
vertex.setColor(packedColor); // Packed color
else if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<VertexCT> g_VertexCT(VERTEX_CT_OP);
class VertexCNT : public Record
{
public:
VertexCNT() {}
META_Record(VertexCNT)
protected:
virtual ~VertexCNT() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int colorNameIndex = in.readInt16();
uint16 flags = in.readUInt16();
osg::Vec3d coord = in.readVec3d();
osg::Vec3f normal = in.readVec3f();
osg::Vec2f uv = in.readVec2f();
osg::Vec4f packedColor = in.readColor32();
int colorIndex = in.readInt32(-1);
Vertex vertex;
vertex.setCoord(coord*document.unitScale());
vertex.setNormal(normal);
vertex.setUV(uv);
// color
if (flags & PACKED_COLOR)
vertex.setColor(packedColor); // Packed color
else if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<VertexCNT> g_VertexCNT(VERTEX_CNT_OP);
/** Absolut Vertex -
* version < 13
*/
class AbsoluteVertex : public Record
{
public:
AbsoluteVertex() {}
META_Record(AbsoluteVertex)
protected:
virtual ~AbsoluteVertex() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int32 x = in.readInt32();
int32 y = in.readInt32();
int32 z = in.readInt32();
Vertex vertex;
// coord
vertex.setCoord(osg::Vec3(x,y,z) * document.unitScale());
// optional texture coordinates
if (in().tellg() < in.getEndOfRecord())
{
osg::Vec2f uv = in.readVec2f();
vertex.setUV(uv);
}
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<AbsoluteVertex> g_AbsoluteVertex(OLD_ABSOLUTE_VERTEX_OP);
/** Shaded Vertex
* version < 13
*/
class ShadedVertex : public Record
{
public:
ShadedVertex() {}
META_Record(ShadedVertex)
protected:
virtual ~ShadedVertex() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int32 x = in.readInt32();
int32 y = in.readInt32();
int32 z = in.readInt32();
uint8 edgeFlag = in.readUInt8();
uint8 shadingFlag = in.readUInt8();
int colorIndex = (int)in.readInt16();
Vertex vertex;
// coord
vertex.setCoord(osg::Vec3(x,y,z) * document.unitScale());
// color
if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
// optional texture coordinates
if (in().tellg() < in.getEndOfRecord())
{
osg::Vec2f uv = in.readVec2f();
vertex.setUV(uv);
}
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<ShadedVertex> g_ShadedVertex(OLD_SHADED_VERTEX_OP);
/** Normal Vertex
* version < 13
*/
class NormalVertex : public Record
{
public:
NormalVertex() {}
META_Record(NormalVertex)
protected:
virtual ~NormalVertex() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
int32 x = in.readInt32();
int32 y = in.readInt32();
int32 z = in.readInt32();
uint8 edgeFlag = in.readUInt8();
uint8 shadingFlag = in.readUInt8();
int colorIndex = (int)in.readInt16();
osg::Vec3f normal = in.readVec3d();
Vertex vertex;
vertex.setCoord(osg::Vec3(x,y,z) * document.unitScale());
vertex.setNormal(normal / (float)(1L<<30));
// color
if (colorIndex >= 0)
vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool
// optional texture coordinates
if (in().tellg() < in.getEndOfRecord())
{
osg::Vec2f uv = in.readVec2f();
vertex.setUV(uv);
}
if (_parent.valid())
_parent->addVertex(vertex);
}
};
RegisterRecordProxy<NormalVertex> g_NormalVertex(OLD_NORMAL_VERTEX_OP);
} // end namespace

View File

@@ -0,0 +1,123 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_OPCODES_H
#define FLT_OPCODES_H
namespace flt {
enum Opcodes
{
UNKNOWN_OP = 0,
HEADER_OP = 1,
GROUP_OP = 2,
OLD_LOD_OP = 3,
OBJECT_OP = 4,
FACE_OP = 5,
OLD_ABSOLUTE_VERTEX_OP = 7,
OLD_SHADED_VERTEX_OP = 8,
OLD_NORMAL_VERTEX_OP = 9,
PUSH_LEVEL_OP = 10,
POP_LEVEL_OP = 11,
DOF_OP = 14,
PUSH_SUBFACE_OP = 19,
POP_SUBFACE_OP = 20,
PUSH_EXTENSION_OP = 21,
POP_EXTENSION_OP = 22,
CONTINUATION_OP = 23,
COMMENT_OP = 31,
COLOR_PALETTE_OP = 32,
LONG_ID_OP = 33,
OLD_TRANSLATE_OP = 40,
OLD_ROTATE_ABOUT_POINT_OP = 41,
OLD_ROTATE_ABOUT_EDGE_OP = 42,
OLD_SCALE_OP = 43,
OLD_TRANSLATE2_OP = 44,
OLD_NONUNIFORM_SCALE_OP = 45,
OLD_ROTATE_ABOUT_POINT2_OP = 46,
OLD_ROTATE_SCALE_TO_POINT_OP = 47,
OLD_PUT_TRANSFORM_OP = 48,
MATRIX_OP = 49,
VECTOR_OP = 50,
OLD_BOUNDING_BOX_OP = 51,
MULTITEXTURE_OP = 52,
UV_LIST_OP = 53,
BINARY_SEPARATING_PLANE_OP = 55,
REPLICATE_OP = 60,
INSTANCE_REFERENCE_OP = 61,
INSTANCE_DEFINITION_OP = 62,
EXTERNAL_REFERENCE_OP = 63,
TEXTURE_PALETTE_OP = 64,
OLD_EYEPOINT_PALETTE_OP = 65,
OLD_MATERIAL_PALETTE_OP = 66,
VERTEX_PALETTE_OP = 67,
VERTEX_C_OP = 68,
VERTEX_CN_OP = 69,
VERTEX_CNT_OP = 70,
VERTEX_CT_OP = 71,
VERTEX_LIST_OP = 72,
LOD_OP = 73,
BOUNDING_BOX_OP = 74,
ROTATE_ABOUT_EDGE_OP = 76,
SCALE_OP = 77,
TRANSLATE_OP = 78,
NONUNIFORM_SCALE_OP = 79,
ROTATE_ABOUT_POINT_OP = 80,
ROTATE_SCALE_TO_POINT_OP = 81,
PUT_TRANSFORM_OP = 82,
EYEPOINT_AND_TRACKPLANE_PALETTE_OP = 83,
MESH_OP = 84,
LOCAL_VERTEX_POOL_OP = 85,
MESH_PRIMITIVE_OP = 86,
ROAD_SEGMENT_OP = 87,
ROAD_ZONE_OP = 88,
MORPH_VERTEX_LIST_OP = 89,
LINKAGE_PALETTE_OP = 90,
SOUND_OP = 91,
ROAD_PATH_OP = 92,
SOUND_PALETTE_OP = 93,
GENERAL_MATRIX_OP = 94,
TEXT_OP = 95,
SWITCH_OP = 96,
LINE_STYLE_PALETTE_OP = 97,
CLIP_REGION_OP = 98,
EXTENSION_OP = 100,
LIGHT_SOURCE_OP = 101,
LIGHT_SOURCE_PALETTE_OP = 102,
BOUNDING_SPHERE_OP = 105,
BOUNDING_CYLINDER_OP = 106,
BOUNDING_CONVEX_HULL_OP = 107,
BOUNDING_VOLUME_CENTER_OP = 108,
BOUNDING_VOLUME_ORIENTATION_OP = 109,
HISTOGRAM_BOUNDING_VOLUME_OP = 110,
LIGHT_POINT_OP = 111,
TEXTURE_MAPPING_PALETTE_OP = 112,
MATERIAL_PALETTE_OP = 113,
NAME_TABLE_OP = 114,
CAT_OP = 115,
CAT_DATA_OP = 116,
BOUNDING_HISTOGRAM = 119,
PUSH_ATTRIBUTE_OP = 122,
POP_ATTRIBUTE_OP = 123,
ADAPTIVE_ATTRIBUTE_OP = 125,
CURVE_NODE_OP = 126,
ROAD_CONSTRUCTION_OP = 127,
LIGHT_POINT_APPEARANCE_PALETTE_OP = 128,
LIGHT_POINT_ANIMATION_PALETTE_OP = 129,
INDEXED_LIGHT_POINT_OP = 130,
LIGHT_POINT_SYSTEM_OP = 131,
INDEXED_STRING_OP = 132,
SHADER_PALETTE_OP = 133
};
} // end namespace
#endif

View File

@@ -0,0 +1,38 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#ifndef FLT_TYPES_H
#define FLT_TYPES_H 1
namespace flt {
#if defined(_MSC_VER)
typedef __int8 int8;
typedef unsigned __int8 uint8;
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef float float32;
typedef double float64;
#else
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef float float32;
typedef double float64;
#endif
} // end namespace
#endif

View File

@@ -14,6 +14,7 @@ CXXFILES = \
LightPointNode.cpp\
MultiSwitch.cpp\
OverlayNode.cpp\
OpenFlightOptimizer.cpp\
ScalarBar.cpp\
ScalarsToColors.cpp\
Sector.cpp\

View File

@@ -0,0 +1,239 @@
//
// OpenFlight<68> loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <osgSim/OpenFlightOptimizer>
#include <osg/Notify>
#include <osg/Geode>
#include <osgUtil/Tesselator>
#include <osgUtil/Optimizer>
#include <vector>
#include <map>
using namespace osgFlightUtil;
void Optimizer::optimize(osg::Node* node)
{
unsigned int options = 0;
const char* env = getenv("OSG_FLIGHTUTIL_OPTIMIZER");
if (env)
{
std::string str(env);
if(str.find("OFF")!=std::string::npos) options = 0;
if(str.find("~DEFAULT")!=std::string::npos) options ^= DEFAULT_OPTIMIZATIONS;
else if(str.find("DEFAULT")!=std::string::npos) options |= DEFAULT_OPTIMIZATIONS;
if(str.find("~TESSELATE_POLYGON")!=std::string::npos) options ^= TESSELATE_POLYGON;
else if(str.find("TESSELATE_POLYGON")!=std::string::npos) options |= TESSELATE_POLYGON;
if(str.find("~MAKE_LIT")!=std::string::npos) options ^= MAKE_LIT;
else if(str.find("MAKE_LIT")!=std::string::npos) options |= MAKE_LIT;
if(str.find("~MERGE_GEODES")!=std::string::npos) options ^= MERGE_GEODES;
else if(str.find("MERGE_GEODES")!=std::string::npos) options |= MERGE_GEODES;
}
else
{
options = DEFAULT_OPTIMIZATIONS;
}
optimize(node,options);
}
void Optimizer::optimize(osg::Node* node, unsigned int options)
{
if (options & TESSELATE_POLYGON)
{
osg::notify(osg::INFO)<<"osgFlightUtil::Optimizer::optimize() doing TESSELATE_POLYGON"<<std::endl;
TesselateVisitor visitor;
node->accept(visitor);
}
if (options & MAKE_LIT)
{
osg::notify(osg::INFO)<<"osgFlightUtil::Optimizer::optimize() doing MAKE_LIT"<<std::endl;
MakeLitVisitor visitor;
node->accept(visitor);
}
if (options & MERGE_GEODES)
{
osg::notify(osg::INFO)<<"osgFlightUtil::Optimizer::optimize() doing MERGE_GEODES"<<std::endl;
MergeGeodesVisitor visitor;
node->accept(visitor);
}
}
void Optimizer::TesselateVisitor::apply(osg::Geode& geode)
{
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geometry)
{
if (hasPolygons(*geometry))
{
// Tesselate
osgUtil::Tesselator tesselator;
tesselator.retesselatePolygons(*geometry);
}
}
}
}
bool Optimizer::TesselateVisitor::hasPolygons(osg::Geometry& geometry)
{
for (unsigned int i=0; i<geometry.getNumPrimitiveSets(); ++i)
{
if (geometry.getPrimitiveSet(i)->getMode() == osg::PrimitiveSet::POLYGON)
return true;
}
return false;
}
void Optimizer::MakeLitVisitor::apply(osg::Geode& /*geode*/)
{
#if 0 // TODO
osg::StateSet* stateset = geode.getStateSet();
if (stateset)
{
// Not lit?
if (!(stateset->getMode(GL_LIGHTING)&osg::StateAttribute::ON))
{
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geometry)
{
if () TODO Compare vertex array length and normal array length + normal binding.
{
// generate normals
osgUtil::SmoothingVisitor smoother;
smoother.smooth(*geometry);
}
}
}
}
}
#endif
}
/** Need to share stateset before merging geodes.
*/
class GeodeStateOptimizer : public osgUtil::Optimizer::StateVisitor
{
public:
GeodeStateOptimizer():
osgUtil::Optimizer::StateVisitor() {}
void optimize(osg::Group& group)
{
for (unsigned int i=0; i<group.getNumChildren(); ++i)
{
osg::Node* child = group.getChild(i);
if (typeid(*child)==typeid(osg::Geode))
{
osg::Geode* geode = (osg::Geode*)child;
addStateSet(geode->getStateSet(),geode);
}
}
osgUtil::Optimizer::StateVisitor::optimize();
}
};
void Optimizer::MergeGeodesVisitor::apply(osg::Group& group)
{
mergeGeodes(group);
traverse(group);
}
// Requires shared stateset to work. Run GeodeStateOptimizer before MergeGeodesVisitor.
struct LessGeode
{
bool operator() (const osg::Geode* lhs,const osg::Geode* rhs) const
{
if (lhs->getStateSet()<rhs->getStateSet()) return true;
// if (rhs->getStateSet()<lhs->getStateSet()) return false;
return false;
}
};
void Optimizer::MergeGeodesVisitor::mergeGeodes(osg::Group& group)
{
{
GeodeStateOptimizer gsopt;
gsopt.optimize(group);
}
typedef std::vector<osg::Geode*> DuplicateList;
typedef std::map<osg::Geode*,DuplicateList,LessGeode> GeodeDuplicateMap;
GeodeDuplicateMap geodeDuplicateMap;
for (unsigned int i=0; i<group.getNumChildren(); ++i)
{
osg::Node* child = group.getChild(i);
if (typeid(*child)==typeid(osg::Geode))
{
osg::Geode* geode = (osg::Geode*)child;
geodeDuplicateMap[geode].push_back(geode);
}
}
// merge
for(GeodeDuplicateMap::iterator itr=geodeDuplicateMap.begin();
itr!=geodeDuplicateMap.end();
++itr)
{
if (itr->second.size()>1)
{
osg::Geode* lhs = itr->second[0];
for(DuplicateList::iterator dupItr=itr->second.begin()+1;
dupItr!=itr->second.end();
++dupItr)
{
osg::Geode* rhs = *dupItr;
if (mergeGeode(*lhs,*rhs))
{
group.removeChild(rhs);
static int co = 0;
osg::notify(osg::INFO)<<"merged and removed Geode "<<++co<<std::endl;
}
}
}
}
}
bool Optimizer::MergeGeodesVisitor::mergeGeode(osg::Geode& lhs, osg::Geode& rhs)
{
for (unsigned int i=0; i<rhs.getNumDrawables(); ++i)
{
lhs.addDrawable(rhs.getDrawable(i));
}
return true;
}

View File

@@ -13,6 +13,7 @@ CXXFILES =\
LightPointNode.cpp\
LightPointSystem.cpp\
MultiSwitch.cpp\
OpenFlightOptimizer.cpp\
OverlayNode.cpp\
ScalarBar.cpp\
ScalarsToColors.cpp\

View File

@@ -0,0 +1,57 @@
// ***************************************************************************
//
// Generated automatically by genwrapper.
// Please DO NOT EDIT this file!
//
// ***************************************************************************
#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/Attributes>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Node>
#include <osgSim/OpenFlightOptimizer>
// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif
BEGIN_ENUM_REFLECTOR(osgFlightUtil::Optimizer::OptimizationOptions)
I_EnumLabel(osgFlightUtil::Optimizer::TESSELATE_POLYGON);
I_EnumLabel(osgFlightUtil::Optimizer::MERGE_GEODES);
I_EnumLabel(osgFlightUtil::Optimizer::MAKE_LIT);
I_EnumLabel(osgFlightUtil::Optimizer::DEFAULT_OPTIMIZATIONS);
I_EnumLabel(osgFlightUtil::Optimizer::ALL_OPTIMIZATIONS);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osgFlightUtil::Optimizer)
I_Constructor0();
I_Method1(void, optimize, IN, osg::Node *, node);
I_Method2(void, optimize, IN, osg::Node *, node, IN, unsigned int, options);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgFlightUtil::Optimizer::MakeLitVisitor)
I_BaseType(osg::NodeVisitor);
I_Constructor0();
I_Method1(void, apply, IN, osg::Geode &, geode);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgFlightUtil::Optimizer::MergeGeodesVisitor)
I_BaseType(osg::NodeVisitor);
I_Constructor0();
I_Method1(void, apply, IN, osg::Group &, group);
I_Method1(void, mergeGeodes, IN, osg::Group &, group);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgFlightUtil::Optimizer::TesselateVisitor)
I_BaseType(osg::NodeVisitor);
I_Constructor0();
I_Method1(void, apply, IN, osg::Geode &, geode);
END_REFLECTOR