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:
@@ -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 \
|
||||
|
||||
@@ -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>
|
||||
|
||||
222
VisualStudio/osgPlugins/OpenFlight/OpenFlight.dsp
Normal file
222
VisualStudio/osgPlugins/OpenFlight/OpenFlight.dsp
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
114
include/osgSim/OpenFlightOptimizer
Normal file
114
include/osgSim/OpenFlightOptimizer
Normal 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
|
||||
@@ -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");
|
||||
|
||||
269
src/osgPlugins/OpenFlight/AncillaryRecords.cpp
Normal file
269
src/osgPlugins/OpenFlight/AncillaryRecords.cpp
Normal 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
|
||||
|
||||
76
src/osgPlugins/OpenFlight/AttrData.cpp
Normal file
76
src/osgPlugins/OpenFlight/AttrData.cpp
Normal 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)
|
||||
{}
|
||||
|
||||
310
src/osgPlugins/OpenFlight/AttrData.h
Normal file
310
src/osgPlugins/OpenFlight/AttrData.h
Normal 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
|
||||
|
||||
|
||||
210
src/osgPlugins/OpenFlight/ControlRecords.cpp
Normal file
210
src/osgPlugins/OpenFlight/ControlRecords.cpp
Normal 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
|
||||
|
||||
|
||||
|
||||
210
src/osgPlugins/OpenFlight/DataInputStream.cpp
Normal file
210
src/osgPlugins/OpenFlight/DataInputStream.cpp
Normal 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);
|
||||
}
|
||||
|
||||
61
src/osgPlugins/OpenFlight/DataInputStream.h
Normal file
61
src/osgPlugins/OpenFlight/DataInputStream.h
Normal 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
|
||||
|
||||
114
src/osgPlugins/OpenFlight/Document.cpp
Normal file
114
src/osgPlugins/OpenFlight/Document.cpp
Normal 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;
|
||||
}
|
||||
221
src/osgPlugins/OpenFlight/Document.h
Normal file
221
src/osgPlugins/OpenFlight/Document.h
Normal 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
|
||||
34
src/osgPlugins/OpenFlight/GNUmakefile
Normal file
34
src/osgPlugins/OpenFlight/GNUmakefile
Normal 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
|
||||
625
src/osgPlugins/OpenFlight/GeometryRecords.cpp
Normal file
625
src/osgPlugins/OpenFlight/GeometryRecords.cpp
Normal 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
|
||||
314
src/osgPlugins/OpenFlight/LightPointRecords.cpp
Normal file
314
src/osgPlugins/OpenFlight/LightPointRecords.cpp
Normal 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);
|
||||
|
||||
635
src/osgPlugins/OpenFlight/PaletteRecords.cpp
Normal file
635
src/osgPlugins/OpenFlight/PaletteRecords.cpp
Normal 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
|
||||
|
||||
|
||||
121
src/osgPlugins/OpenFlight/Pools.cpp
Normal file
121
src/osgPlugins/OpenFlight/Pools.cpp
Normal 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;
|
||||
}
|
||||
214
src/osgPlugins/OpenFlight/Pools.h
Normal file
214
src/osgPlugins/OpenFlight/Pools.h
Normal 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
|
||||
747
src/osgPlugins/OpenFlight/PrimaryRecords.cpp
Normal file
747
src/osgPlugins/OpenFlight/PrimaryRecords.cpp
Normal 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
|
||||
177
src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp
Normal file
177
src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp
Normal 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;
|
||||
187
src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp
Normal file
187
src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp
Normal 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;
|
||||
138
src/osgPlugins/OpenFlight/Record.cpp
Normal file
138
src/osgPlugins/OpenFlight/Record.cpp
Normal 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;
|
||||
}
|
||||
114
src/osgPlugins/OpenFlight/Record.h
Normal file
114
src/osgPlugins/OpenFlight/Record.h
Normal 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
|
||||
126
src/osgPlugins/OpenFlight/RecordInputStream.cpp
Normal file
126
src/osgPlugins/OpenFlight/RecordInputStream.cpp
Normal 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();
|
||||
}
|
||||
49
src/osgPlugins/OpenFlight/RecordInputStream.h
Normal file
49
src/osgPlugins/OpenFlight/RecordInputStream.h
Normal 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
|
||||
47
src/osgPlugins/OpenFlight/Registry.cpp
Normal file
47
src/osgPlugins/OpenFlight/Registry.cpp
Normal 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;
|
||||
}
|
||||
66
src/osgPlugins/OpenFlight/Registry.h
Normal file
66
src/osgPlugins/OpenFlight/Registry.h
Normal 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
|
||||
23
src/osgPlugins/OpenFlight/ReservedRecords.cpp
Normal file
23
src/osgPlugins/OpenFlight/ReservedRecords.cpp
Normal 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);
|
||||
|
||||
|
||||
|
||||
|
||||
121
src/osgPlugins/OpenFlight/RoadRecords.cpp
Normal file
121
src/osgPlugins/OpenFlight/RoadRecords.cpp
Normal 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
|
||||
55
src/osgPlugins/OpenFlight/Vertex.cpp
Normal file
55
src/osgPlugins/OpenFlight/Vertex.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
44
src/osgPlugins/OpenFlight/Vertex.h
Normal file
44
src/osgPlugins/OpenFlight/Vertex.h
Normal 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
|
||||
324
src/osgPlugins/OpenFlight/VertexRecords.cpp
Normal file
324
src/osgPlugins/OpenFlight/VertexRecords.cpp
Normal 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
|
||||
123
src/osgPlugins/OpenFlight/opcodes.h
Normal file
123
src/osgPlugins/OpenFlight/opcodes.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
38
src/osgPlugins/OpenFlight/types.h
Normal file
38
src/osgPlugins/OpenFlight/types.h
Normal 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
|
||||
@@ -14,6 +14,7 @@ CXXFILES = \
|
||||
LightPointNode.cpp\
|
||||
MultiSwitch.cpp\
|
||||
OverlayNode.cpp\
|
||||
OpenFlightOptimizer.cpp\
|
||||
ScalarBar.cpp\
|
||||
ScalarsToColors.cpp\
|
||||
Sector.cpp\
|
||||
|
||||
239
src/osgSim/OpenFlightOptimizer.cpp
Normal file
239
src/osgSim/OpenFlightOptimizer.cpp
Normal 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;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ CXXFILES =\
|
||||
LightPointNode.cpp\
|
||||
LightPointSystem.cpp\
|
||||
MultiSwitch.cpp\
|
||||
OpenFlightOptimizer.cpp\
|
||||
OverlayNode.cpp\
|
||||
ScalarBar.cpp\
|
||||
ScalarsToColors.cpp\
|
||||
|
||||
57
src/osgWrappers/osgSim/OpenFlightOptimizer.cpp
Normal file
57
src/osgWrappers/osgSim/OpenFlightOptimizer.cpp
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user